2 class weak_ptr
shared_ptr的限制:
1. 环式指向: 两个shared_ptr的对象互相指向对方,如果想要释放它们,shared_ptr不会释放数据,因为它们的unse_count()为1;
2. “明确想共享,但是不愿拥有”:标准库定义了class weak_ptr,允许“共享但是不拥有”某对象;一旦拥有该对象的最后一个shared_ptr失去拥有权之后,weak_ptr自动成空;
2.1 构造函数
因此,class weak_ptr只接受一个shared_ptr的构造函数:
//default (1)
constexpr weak_ptr() noexcept;
//copy (2)
weak_ptr (const weak_ptr& x) noexcept;
template <class U> weak_ptr (const weak_ptr<U>& x) noexcept;
//from shared_ptr (3)
template <class U> weak_ptr (const shared_ptr<U>& x) noexcept;
说明:
1. weak_ptr不能使用操作符*
和->
访问weak_ptr指向的对象;必须例外建立一个shared_ptr
原因:
(1).weak_ptr指向的对象可能不存在,使用它的函数lock()可以返回一个指向共享对象的shared_ptr,不存在,返回一个空的shared_ptr;
(2).当所指的对象正被处理的时候,shared pointer无法被释放
2.2 weak_ptr的部分操作
表达式 | 效果 |
---|---|
weak_ptr<T> w | 空weak_ptr,可指向T类型的对象 |
weak_ptr<T>w(sp) | 与shared_ptr sp 指向相同对象的weak_ptr。T必须能够转化为sp指向的类型; |
w = p | p 可以是一个shared_ptr或者一个weak_ptr,赋值后w与p共享对象 |
w.reset() | 将 w置为空 |
w.use_count() | 与w共享对象的shared_ptr的数量 |
w.expired() | 若w.use_count() 为0,返回true,否则返回false |
w.lock() | 如果w.expired()为true,返回一个空的shared_ptr,否则返回一个指向w的对象的shared_ptr; |
不能直接用weak_ptr访问对象,使用shared_ptr:
if(shared_ptr<int> np = wp.lock())//如果np不为空条件成立
{
//在if中,np与p共享对象
}
这个时候,使用np访问对象是安全的;