shared_ptr实现思想
时间: 2024-04-19 22:20:47 浏览: 94
shared_ptr是C++标准库中的智能指针之一,用于管理动态分配的内存资源。它的实现思是基于引用计数。
当使用shared_ptr时,它会在堆上一个控制块(control block),该控制块包含两部分信息:指向动态分配内的指针和一个引用计数器引用计数器记录了有多少个shared_ptr对象共享同一块内存。
当我们创建一个_ptr对象并将其指向某个动态分配的内存时,引用计数器会被初始化为1。当我们将这个shared_ptr对象赋值给其他shared_ptr对象时,引用计数器会递增。当某个shared_ptr对象超出作用域或被显式地置为nullptr时,引用计数器会递减。当引用计数器变为0时,表示没有任何shared_ptr对象指向该块内存,此时会自动释放该内存。
shared_ptr的实现还考虑了线程安全性。在多线程环境下,对引用计数器的操作需要进行同步,以避免竞争条件。
总结一下,shared_ptr通过引用计数的方式来管理动态分配的内存资源,确保资源在不再被使用时能够被正确释放,避免内存泄漏。
相关问题
27、四种智能指针及底层实现:auto_ptr、unique_ptr、shared_ptr、weak_ptr
1. auto_ptr:已被废弃,不建议使用。它的底层实现采用了所有权转移的思想,即将指针的所有权转移给另一个对象,原指针将被置空,保证只有一个对象拥有内存资源,从而避免内存泄漏。
2. unique_ptr:C++11 引入的独占智能指针,使用了 move 语义,可以将所有权转移给其他对象,但不允许被复制。它的底层实现采用了 RAII 技术,即在对象生命周期结束时自动释放内存资源,保证内存安全。
3. shared_ptr:C++11 引入的共享智能指针,可以被多个对象共享,采用引用计数技术,在其中一个对象不再需要该内存资源时释放内存。它的底层实现采用了一个控制块,存储内存资源的引用计数和指向内存资源的指针,保证了内存资源的安全和正确释放。
4. weak_ptr:是 shared_ptr 的一种扩展,可以解决 shared_ptr 的循环引用问题。它的底层实现也采用了引用计数技术,但它不会增加内存资源的引用计数,只是提供了一种访问共享内存资源的方式,当共享内存资源被释放时,弱指针将自动失效,避免了野指针问题。
shared_ptr的代码实现
shared_ptr是C++11中的一种智能指针,用于管理动态分配的内存资源,它基于引用计数的思想,可以让多个智能指针共享同一个对象,以便有效地避免内存泄漏和重复释放等问题。
以下是shared_ptr的精简版代码实现:
```c++
template <typename T>
class shared_ptr {
public:
// 构造函数
shared_ptr(T* ptr = nullptr) : m_ptr(ptr), m_ref_count(new size_t(1)) {}
// 拷贝构造函数
shared_ptr(const shared_ptr<T>& other) {
m_ptr = other.m_ptr;
m_ref_count = other.m_ref_count;
++(*m_ref_count);
}
// 析构函数
~shared_ptr() {
release();
}
// 获取指针
T* get() const {
return m_ptr;
}
// 重载箭头运算符
T* operator->() const {
return m_ptr;
}
// 重载解引用运算符
T& operator*() const {
return *m_ptr;
}
// 获取引用计数
size_t use_count() const {
return *m_ref_count;
}
// 重载赋值运算符
shared_ptr<T>& operator=(const shared_ptr<T>& other) {
if (this != &other) {
release();
m_ptr = other.m_ptr;
m_ref_count = other.m_ref_count;
++(*m_ref_count);
}
return *this;
}
// 释放资源
void release() {
if (*m_ref_count == 1) {
delete m_ref_count;
delete m_ptr;
} else {
--(*m_ref_count);
}
m_ref_count = nullptr;
m_ptr = nullptr;
}
private:
T* m_ptr; // 指向对象的指针
size_t* m_ref_count; // 引用计数指针
};
```
这个实现中,m_ptr指向被管理的对象,m_ref_count指向引用计数。在构造函数中,m_ptr被赋值为传递进来的指针,m_ref_count被初始化为1。在拷贝构造函数中,m_ptr和m_ref_count都被赋值为other的成员变量,而other的引用计数也被加1。在析构函数中,如果引用计数为1,则删除m_ptr和m_ref_count,否则引用计数减1。在重载赋值运算符中,如果this指针不等于other,则先调用release()方法释放当前对象的资源,然后再将m_ptr和m_ref_count赋值为other的成员变量,并将引用计数加1。
这样一来,就可以通过shared_ptr来管理动态分配的内存资源,达到自动释放的效果。同时,由于shared_ptr基于引用计数的思想,可以让多个智能指针共享同一个对象,以便有效地避免内存泄漏和重复释放等问题。
阅读全文