shared_ptr类
shared_ptr和unique_ptr都支持的操作:
操作 | 解释 |
---|---|
shared_ptr<T> sp unique_ptr<T> up |
创建空智能指针,可以指向类型是T 的对象 |
p |
将p 用作一个条件判断,若p 指向一个对象,则为true |
*p |
解引用p ,获得它指向的对象。 |
p->mem |
等价于(*p).mem |
p.get() |
返回p 中保存的指针,要小心使用,若智能指针释放了对象,返回的指针所指向的对象也就消失了。 |
swap(p, q) p.swap(q) |
交换p 和q 中的指针 |
shared_ptr独有的操作:
操作 | 解释 |
---|---|
make_shared<T>(args) |
返回一个shared_ptr ,指向一个动态分配的类型为T 的对象。使用args 初始化此对象。 |
shared_ptr<T>p(q) |
p 是shared_ptr q 的拷贝;此操作会递增q 中的计数器。q 中的指针必须能转换为T* |
p = q |
p 和q 都是shared_ptr ,所保存的指针必须能互相转换。此操作会递减p 的引用计数,递增q 的引用计数;若p 的引用计数变为0,则将其管理的原内存释放。 |
p.unique() |
若p.use_count() 是1,返回true ;否则返回false |
p.use_count() |
返回与p 共享对象的智能指针数量;可能很慢,主要用于调试。 |
shared_ptr和new结合使用
定义和改变shared_ptr的其他方法:
shared_ptr<int> p(new int(42)); //shared_ptr指向一个值为42的int,两者结合使用仅只能以这种形式出现,可用但最好别用
shared_ptr<int> p = new int(42);//错误,智能指针的构函是explicit的,普通指针不能隐式转化为智能指针,只有上个可用
使用普通指针访问智能指针所负责对象很危险,因为不知对象何时被销毁可能访问到不存在内存
不要使用成函get初始化另一个智能指针或为其赋值
操作 | 解释 |
---|---|
shared_ptr<T> p(q) |
p 管理内置指针q 所指向的对象;q 必须指向new 分配的内存,且能够转换为T* 类型 。(即用普通指针初始化智指) |
shared_ptr<T> p(u) |
p 从unique_ptr u 那里接管了对象的所有权;将u 置为空 |
shared_ptr<T> p(q, d) |
p 接管了内置指针q 所指向的对象的所有权。q 必须能转换为T* 类型。p 将使用可调用对象d 来代替delete 。 |
shared_ptr<T> p(p2, d) |
p 是shared_ptr p2 的拷贝,唯一的区别是p 将可调用对象d 来代替delete 。 |
p.reset() |
若p 是唯一指向其对象的shared_ptr ,reset 会释放此对象。若传递了可选的参数内置指针q ,会令p 指向q ,否则会将p 置空。若还传递了参数d ,则会调用d 而不是delete 来释放q 。 |
p.reset(q) |
同上 |
p.reset(q, d) |
同上 |
unique_ptr
没有类似make_shared的标准库返回一个unique_ptr,定义时需将其绑定到一个new返回的指针。
unique_ptr<int> p (new int(42));
unique_ptr<int> p;
unique_ptr特有操作:
操作 | 解释 |
---|---|
unique_ptr<T> u unique_ptr<T, D> u2 |
空unique_ptr ,可以指向类型是T 的对象。u1 会使用delete 来是释放它的指针。 |
u2 会使用一个类型为D 的可调用对象来释放它的指针。 |
|
unique_ptr<T, D> u(d) |
空unique_ptr ,指向类型为T 的对象,用类型为D 的对象d 代替delete |
u = nullptr |
释放u 指向的对象,将u 置为空。 |
u.release() |
u 放弃对指针的控制权,返回指针,并将u 置空。 |
u.reset() |
释放u 指向的对象 |
u.reset(q) |
令u 指向q 指向的对象 |
u.reset(nullptr) |
将u 置空 |
删除器的类型D要在创建unique的时候提供,放在<>中的第二个类型用decltype()*提供可调用的函数指针,并在d的位置放入替代delete的函数名称
ep: unique_ptr<connection, decltype(end_connection)*> p(&c, end_connection);
weak_ptr
- 创建一个weak_ptr时要用一个shared_ptr来初始化它。
- auto p = make_shared<inr>(42); weak_ptr<int> wp(p);
由于对象不一定存在所以在访问weak_ptr管理的对象之前必须使用成员函数lock()检查对象是否存在,如果存在则返回指向共享对象的shared_ptr。
- if(shared_ptr<int> p == wp.lock()) { /*访问管理对象的语句*/} //p和np共享对象
weak_ptr操作:
操作 | 解释 |
---|---|
weak_ptr<T> w |
空weak_ptr 可以指向类型为T 的对象 |
weak_ptr<T> w(sp) |
与shared_ptr 指向相同对象的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() |
如果expired 为true ,则返回一个空shared_ptr ;否则返回一个指向w 的对象的shared_ptr 。 |