shared_ptr和unique_ptr都支持的操作:
*p p->mem p.get() 返回p中保存的指针,智能指针p在某些情况下可以代替p.get(),比如cout<<p 输出内部指针 p.reset() 放弃内部对象的所有权,等价于 p = nullptr p.reset(T *ptr) 变更拥有的对象 在shared中,reset会造成引用计数的减少,为0时删除;unique中直接删除 swap(p, q) 交换p和q中的指针不能将普通指针直接赋值给智能指针。
不要使用同一个原始指针构造 shared_ptr:
int *num = new int(23); std::shared_ptr<int> p1(num); std::shared_ptr<int> p2(p1); // 正确使用方法 std::shared_ptr<int> p3(num); // 不推荐 std::cout << "p1 Reference = " << p1.use_count() << std::endl; // 输出 2 std::cout << "p2 Reference = " << p2.use_count() << std::endl; // 输出 2 std::cout << "p3 Reference = " << p3.use_count() << std::endl; // 输出 1虽然p1 p3指向相同对象,但并没有统一,当p1超出作用域时会调用delete释放num内存,此时num成了悬空指针,当p3超出作用域再次delete的时候就可能会出错。
weak_ptr 是为了配合shared_ptr而引入的一种智能指针,对被 shared_ptr 管理的对象存在非拥有性(“弱”)引用,无法直接访问,也不会影响引用计数。在访问所引用的对象前必须先转换为 shared_ptr。
weak_ptr<T> w 默认构造,空指针 weak_ptr<T> w(p) p为shared或weak,与p指向相同对象。T必须能转换成p指向的类型 w = p 同上 w.reset() 将w置为空 w.use_count() w监视对象的引用计数 w.expired() w指向的对象引用计数是否为0,是为true w.lock() 如果expired为true,返回空shared_ptr;否则返回一个指向w的shared_ptrweak_ptr 用来表达临时所有权的概念:当某个对象只有存在时才需要被访问,而且随时可能被他人删除时,可以使用 weak_ptr 来跟踪该对象。需要获得临时所有权时,则将其转换为 shared_ptr(计数+1)。
if(shared_ptr<int> np = wp.lock()){ //如果np不为空则条件成立,计数暂时+1 // 在if中,np与p共享对象 } //退出if函数体,计数-1恢复weak_ptr 的另一用法是打断 shared_ptr 所管理的对象组成的环状引用。若这种环被孤立(例如无指向环中的外部共享指针),则 shared_ptr 引用计数无法抵达零,而内存被泄露。能令环中的指针之一为弱指针以避免此情况。
shared_ptr的自定义删除器不同于shared_ptr,两者分别代表两种不同的删除器绑定方式: 1.shared_ptr在运行时绑定删除器,删除器保存为一个指针,可以随时通过reset来更改删除器类型,更灵活; 2.unique_ptr在编译时绑定,因为删除器的类型是unique_ptr类型的一部分,更高效。
——《C++primer 5th》P599
自定义删除器的具体写法:https://blog.csdn.net/DumpDoctorWang/article/details/88598015
unique_ptr独占指向的对象,不能拷贝或赋值unique_ptr,但可以通过调用release或reset转移指针所有权:
unique_ptr<A> p(new A); unique_ptr<A> p2(p.release()); unique_ptr<A> p3; p3.reset(p2.release());不能拷贝unique_ptr的规则有一个例外:我们可以拷贝或赋值一个将要被销毁的unique_ptr。
unique_ptr<int> clone(int p){ unique_ptr<int> ret(new int(p)); //... return ret; }编译器知道要返回的对象将要被销毁。在此情况下,编译器执行移动赋值。
引用计数是atomic,读是安全,多线程写不安全。 https://blog.csdn.net/solstice/article/details/8547547
参考: https://zh.cppreference.com/w/cpp/memory/unique_ptr https://blog.csdn.net/DumpDoctorWang/article/details/88598015 https://blog.csdn.net/shaosunrise/article/details/85228823?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param 《C++primer 5th》
