智能指针
- C++ 四种智能指针,
auto_ptr 、shared_ptr 、weak_ptr 、unique_ptr ,其中后面3个是 C++11 支持的,并且第一个以被弃用。
unique_ptr
shared_ptr
shared_ptr 实现共享式拥有概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放。
- 从名字share就可以看出了资源可以被多个指针共享,它使用计数机制来表明资源被几个指针共享。可以通过成员函数
use_count() 来查看资源的所有者个数。 - 除了可以通过
new 来构造,还可以通过传入auto_ptr, unique_ptr,weak_ptr 来构造。 - 当我们调用
release() 时,当前指针会释放资源所有权,计数减一。当计数等于0时,资源会被释放。 - 它允许共享资源,使用计数器记录资源被 n 个指针共享。
shared_ptr 基于“引用计数”模型实现,多个shared_ptr 可指向同一个动态对象,并维护了一个共享的引用计数器,记录了引用同一对象的shared_ptr 实例的数量。当最后一个指向动态对象的shared_ptr 销毁时,会自动销毁其所指对象(通过delete 操作符)。shared_ptr 的默认能力是管理动态内存,但支持自定义的Deleter 以实现个性化的资源释放动作。shared_ptr 的线程安全问题:
- 同一个
shared_ptr 被多个线程读,是线程安全。 - 同一个
shared_ptr 被多个线程写,不是线程安全的。 - 共享引用计数的不同的
shared_ptr 被多个线程写,是线程安全的。 对于第三点,我们一般采用: 对于线程中传入的外部shared_ptr对象,在线程内部进行一次新的构造,例如: sharedptr AObjTmp = outerSharedptrObj;
weak_ptr
weak_ptr 用于解决“引用计数”模型循环依赖问题,weak_ptr 指向一个对象,并不增减该对象的引用计数器。weak_ptr 用于解决 shared_ptr 相互引用时的死锁问题,如果说 shared_ptr 相互引用,计数器永远不会是0,资源不被释放,weak_ptr 是对象的弱引用,不会增加对象的引用次数,和 shared_ptr 相互转化,shared_ptr 可直接赋值,他可以通过lock() 函数获得 shared_ptr 。weak_ptr 指向shared_ptr 指针指向的对象的内存,却并不拥有该内存。 但是,使用weak_ptr 成员lock ,则可返回其指向内存的一个shared_ptr 对象,且在所指对象内存已经无效时,返回指针空值(nullptr)。- 由于
weak_ptr 是指向shared_ptr 所指向的内存的,所以,weak_ptr 并不能独立存在。
案例
#include <iostream>
#include <memory>
void Check(const weak_ptr<int> &wp)
{
shared_ptr<int> sp = wp.lock();
if (sp != nullptr) {
cout << "The value is " << *sp << endl;
} else {
cout << "Pointer is invalid." << endl;
}
}
int main() {
shared_ptr<int> sp1(new int(10));
shared_ptr<int> sp2 = sp1;
weak_ptr<int> wp = sp1;
cout << *sp1 << endl;
cout << *sp2 << endl;
Check(wp);
sp1.reset();
cout << *sp2 << endl;
Check(wp);
sp2.reset();
Check(wp);
return 0;
}
|