shared_ptr
shared_ptr 允许多个 shared_ptr 共同管理一个指针,每个 shared_ptr 的存在都会增加引用计数
初始化 shared_ptr
// 1. 使用指针来初始化,p 是 A* 类型的
std::shared_ptr<A> q(p);
// 2. 通过其他 shared_ptr 来初始化,p 也是 shared_ptr
std::shared_ptr<A> q(p);
错误的初始化方式:
// p 是指针类型 A*
std::shared_ptr<A> q = p;
如何共享:
// 1. 通过初始化来共享,p 是 shared_ptr
std::shared_ptr<A> q(p);
// 2. 通过赋值来共享,如果 q 原来有指向,则原本引用计数 -1
q = p;
weak_ptr
为什么要有 weak_ptr:
shared_ptr 在两个对象都有成员变量指向对方时,会因为“死锁”而内存泄漏:
struct A {
std::shared_ptr<B> b_in_A;
};
struct B {
std::shared_ptr<A> a_in_B;
};
int main() {
std::shared_ptr<A> a(new A()); // a 的引用计数为 1
std::shared_ptr<B> b(new B()); // b 的引用计数为 1
a.b_in_A = b; // b 的引用计数为 2
b.a_in_B = a; // a 的引用计数为 2
return 0;
}
weak_ptr 不增加引用计数
初始化方法:只能通过 shared_ptr 来初始化
对上述情形的改造方法:
struct A {
std::weak_ptr<B> b_in_A;
};
struct B {
std::shared_ptr<A> a_in_B;
};
int main() {
std::shared_ptr<A> a(new A()); // a 的引用计数为 1
std::shared_ptr<B> b(new B()); // b 的引用计数为 1
a.b_in_A = b; // b 的引用计数为 1
b.a_in_B = a; // a 的引用计数为 2
return 0;
}
weak_ptr 使用需要注意:由于不增加引用计数,不知道内存释放已经被释放,所以不支持 ->
和 *
运算符。通过 expire()
方法可以判断指针是否有效,然后通过 lock()
生成一个新的 shared_ptr
来使用。(也可以直接使用 lock()
来判断指针是否有效)
std::shared_ptr<A> p(new A());
std::weak_ptr<A> q(p);
if (std::shared_ptr<A> t = q.lock()) {
// do something with t
}
unique_ptr
unique_ptr 要有智能指针独占指针
初始化:智能通过指针 A*
来初始化
拷贝:不支持拷贝,除非是函数返回时
释放:
release()
释放指针的所有权,将智能指针置为空,不会释放内存reset()
释放内存,将智能指针置为空