将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。
auto_ptr(已经弃用)
auto_ptr<string> p1 (new string ("aaa));
auto_ptr<string> p2;
p2 = p1; // 不报错
unique_ptr
“独占”所指向的对象 是auto的改进
unique_ptr<string> p1 (new string ("aaa"));
unique_ptr<string> p2;
p2 = p1; // 会报错
// c++14新引入的
unique_ptr<int> p3 = make_unique<int>(34);
// 转移所有权1
unique_ptr<int> p4 = move(p3); // p3变为空
// 把p1指向的这个空间释放掉 p1变为空指针
p1.reset();
// 把p1指向的这个空间变为空的,但并不释放 p1变为空指针
p1.release();
// 转移所有权2 通常用于初始化另一指针
unique_ptr<string> p2(p1.release()); // p1变为空
由于auto ptr允许直接赋值,会导致p1被留下悬挂住,导致危害。因此unique ptr更安全
shared_ptr
允许多个指针指向同一个对象。新增一个时引用计数加1,当过期时引用计数减1。只有引用计数为0时,智能指针才会自动释放引用的内存资源。
// create1
int *p = new int(124);
shared_ptr<int> p1(p);
// create2
shared_ptr<int> p2 = make_shared<int>(42);
// create3
shared_ptr<int> p3 = make_shared<int>();
shared_ptr<int> p3;
// 返回指针本身,输出的话会输出指针地址
p1.get();
// 交换两个指针
swap(p1, p2);
// 引用计数的个数
p1.use_count();
weak_ptr
当两个对象相互使用一个shared_ptr成员变量指向对方,会造成循环引用,使引用计数失效,从而导致内存泄漏。weak_ptr是用来解决shared_ptr相互引用时的死锁问题。
weak ptr 只能‘访问’对象,不能修改对象的生命周期(但shared_ptr指针生命周期结束时,指针指向的区域也会被释放掉)
shared_ptr<int> p1 = make_shared<int>(42);
weak_ptr<int> p2 = p1; // ok
shared_ptr<int> p3 = p2; // 不ok
shared_ptr<int> p4 = p2.lock(); // ok
成员函数:
expired,用来判断weak ptr指向的对象是否存在
lock,返回一个shared_ptr类型的指针
scoped_ptr
也是一个独占性智能指针,但是它不允许转移所有权。它更安全谨慎,但是应用的范围也更狭窄。
更新:weak ptr是如何解决循环引用的问题的?---- 百度面试
把其中一个shared ptr 换成weak ptr