shared_ptr是如何实现的
时间: 2024-04-19 18:18:56 浏览: 95
shared_ptr是通过引用计数的方式实现的。每个shared_ptr对象都有一个指向控制块的指针,控制块中包含了引用计数和指向所管理对象的指针。当一个新的shared_ptr对象被创建时,它会与原有的shared_ptr对象共享同一个控制块,引用计数会加1。当一个shared_ptr对象被销毁时,它会将引用计数减1,如果引用计数变为0,则表示没有任何shared_ptr对象指向该对象,此时控制块会被销毁,从而释放所管理的对象。
相关问题
shared_ptr C++实现
`std::shared_ptr` 是 C++11 标准库中的一种智能指针,它的实现可以借助引用计数来确保在所有引用计数为 0 时自动释放分配的内存。下面是一个简化版的 `shared_ptr` 的实现:
```c++
template <typename T>
class shared_ptr {
public:
shared_ptr(T* ptr = nullptr) : m_ptr(ptr), m_count(new int(1)) {}
shared_ptr(const shared_ptr& other) : m_ptr(other.m_ptr), m_count(other.m_count) { ++(*m_count); }
~shared_ptr() {
if (--(*m_count) == 0) {
delete m_ptr;
delete m_count;
}
}
T& operator*() { return *m_ptr; }
T* operator->() { return m_ptr; }
shared_ptr& operator=(const shared_ptr& other) {
if (this != &other) {
if (--(*m_count) == 0) {
delete m_ptr;
delete m_count;
}
m_ptr = other.m_ptr;
m_count = other.m_count;
++(*m_count);
}
return *this;
}
private:
T* m_ptr;
int* m_count;
};
```
在这个实现中,我们定义了一个 `shared_ptr` 类,它包含了一个指向动态分配内存的指针 `m_ptr` 和一个指向引用计数的指针 `m_count`。在 `shared_ptr` 的构造函数中,我们将 `m_count` 的初始值设为 1,表示当前只有一个 `shared_ptr` 对象引用了这块内存。在 `shared_ptr` 的拷贝构造函数中,我们将 `m_count` 的值加 1,表示多了一个 `shared_ptr` 对象引用了这块内存。在 `shared_ptr` 的析构函数中,我们将 `m_count` 的值减 1,如果引用计数变成了 0,则说明没有任何 `shared_ptr` 对象引用了这块内存,我们就可以释放内存了。在 `shared_ptr` 的赋值运算符中,我们先将 `m_count` 的值减 1,然后检查引用计数是否已经为 0,如果是,则释放内存。然后我们将 `m_ptr` 和 `m_count` 更新为 `other` 的值,并将 `m_count` 的值加 1。
这只是一个简化版的 `shared_ptr` 实现,实际的 `std::shared_ptr` 稍微复杂一些,但基本思路是相同的。
shared_ptr的实现
shared_ptr的实现可以分为两部分:引用计数和资源管理。引用计数是指记录有多少个shared_ptr对象共享同一个资源的计数器,当计数器为0时,资源被释放。资源管理是指shared_ptr对象的构造、拷贝、赋值和析构等操作,它们需要保证引用计数的正确性。
下面是shared_ptr的一个简化实现:
```
template <typename T>
class shared_ptr {
public:
shared_ptr() : ptr(nullptr), ref_count(nullptr) {}
shared_ptr(T* p) : ptr(p), ref_count(new size_t(1)) {}
shared_ptr(const shared_ptr<T>& sp) : ptr(sp.ptr), ref_count(sp.ref_count) {
++(*ref_count);
}
~shared_ptr() {
if (--(*ref_count) == 0) {
delete ptr;
delete ref_count;
}
}
shared_ptr<T>& operator=(const shared_ptr<T>& sp) {
if (this != &sp) {
if (--(*ref_count) == 0) {
delete ptr;
delete ref_count;
}
ptr = sp.ptr;
ref_count = sp.ref_count;
++(*ref_count);
}
return *this;
}
T* get() const {
return ptr;
}
size_t use_count() const {
return *ref_count;
}
private:
T* ptr;
size_t* ref_count;
};
```
在这个实现中,我们使用了一个计数器ref_count来记录有多少个shared_ptr对象共享同一个资源。当一个新的shared_ptr对象被创建时,它的计数器被初始化为1,表示它自己是唯一的资源使用者。当有一个新的shared_ptr对象与它共享同一个资源时,它的计数器加1,表示有多了一个资源使用者。当一个shared_ptr对象被销毁时,它的计数器减1,如果计数器变为0,则表示没有任何资源使用者,此时资源被释放。
除了计数器,我们还需要一个指针ptr来指向所管理的资源。在构造函数中,我们需要传入一个指向资源的指针,然后创建一个新的计数器并初始化为1。在拷贝构造函数和赋值操作符中,我们需要共享已有的计数器,因此直接将ref_count指针赋值给新的shared_ptr对象即可。在析构函数中,我们需要判断计数器是否为0,如果为0,则释放资源和计数器。在get()函数中,我们返回指向资源的指针;在use_count()函数中,我们返回计数器的值。
这个实现仅仅是shared_ptr的一个简化版本,实际的shared_ptr实现可能还包括线程安全、自定义删除器等功能。
阅读全文