首页 » 技术分享 » c++智能指针总结

c++智能指针总结

 
文章目录

2020.4.15 之前一直不愿意用智能指针,想法是因为现在项目不是足够大,认为没必要担心内存泄露的问题,自己控制好即可。这几天在认真拜读陈硕大佬的《c++多线程服务器编程》,认为是一本非常优秀的书籍,很适合我这种从初级往中级程序员发展突破“境界”所用。书里说了一些多线程的原理,c++多线程中使用智能指针是非常合适的,因为没有垃圾回收机制,在对象析构过程中多线程访问对象难免会出问题,不想自己重复造轮子,智能指针是非常合适的选择,原因会在之后分析,当然是借鉴了书中的一些想法。

 

下列博客讲的很好

https://www.cyhone.com/articles/right-way-to-use-cpp-smart-pointer/ 

 

一.基础用法

1.shared_ptr

shared_ptr<string>p1;   //这里声明+定义初始化的时候 已经初始化为0  不用担心野指针的问题。

shared_ptr<string>pi(new string("hello gyf"));

一般初始化
shared_ptr<string>pi(new string("hello gyf")); 

推荐的安全的初始化方式

shared_ptr<string> pint1 = make_shared<string>("safe uage!"); 

 

尽量不要将 shared_ptr指向一个普通指针。

尽量不要用到get()函数 get用来将指针的访问权限传递给代码,只有在确定代码不会delete指针的情况下,才能使用get。特别是,永远不要用get初始化另一个智能指针或者为另一个智能指针赋值。

尽量不使用get()呗

 

 关于mak_shared函数:

最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数,此函数在动态内存中分配一个对象并初始化它,返回此对象的shared_ptr。与只能指针一样,make_shared也定义在头文件memory中。

    shared_ptr<int> p3 = make_shared<int>(42);
    cout<<*p3<<endl;
    shared_ptr<string> pstr = make_shared<string>("99999");
    cout<<*pstr<<endl;
    shared_ptr<int> pint = make_shared<int>(); //!默认初始化为 0
    cout<<*pint<<endl;
    auto pau = make_shared<string>("auto");    //!更简单,更常用的方式。
    cout<<*pau<<endl;
 cout<<p.use_count()<<endl; 这个函数可以知道当前有多少个其他智能指针指向这个对象。

reset()函数

reset会更新(-1)引用计数,如果需要的话,会释放p1指向的对象。reset成员经常与unique一起使用,来控制多个shared_ptr的共享对象。在改变底层对象之前,我们在检查自己是否是当前对象仅有的用户。

反正reset会把当前指针计为空 对象引用计数减1 如果对象引用计数为0 直接析构该对象。

 

 

容器中的shared_ptr-记得用erease节省内存 

对于一块内存,shared_ptr类保证只要有任何shared_ptr对象引用它,他就不会被释放掉。由于这个特性,保证shared_ptr在不用之后不再保留就非常重要了,通常这个过程能够自动执行而不需要人工干预,有一种例外就是我们将shared_ptr放在了容器中。所以永远不要忘记erease不用的shared_ptr。

 

总结

1)不使用相同的内置指针值初始化(或reset)多个智能指针。

2)不delete get函数返回的指针。

3)如果你使用了get返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了。

4)如果你使用智能指针管理的资源不是new分配的内存,记得传递给他一个删除器。

 

2.weak_ptr

1、weak_ptr是什么?

weak_ptr是为了配合shared_ptr而引入的一种智能指针,它指向一个由shared_ptr管理的对象而不影响所指对象的生命周期,也就是将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。不论是否有weak_ptr指向,一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。从这个角度看,weak_ptr更像是shared_ptr的一个助手而不是智能指针。

2、weak_ptr如何使用?

接下来,我们来看看weak_ptr的简单用法。

2.1如何创建weak_ptr实例

当我们创建一个weak_ptr时,需要用一个shared_ptr实例来初始化weak_ptr,由于是弱共享,weak_ptr的创建并不会影响shared_ptr的引用计数值。

具体看这个博文 非常清楚

https://blog.csdn.net/albertsh/article/details/82286999

 

3.unique_ptr

我们大多数场景下用到的应该都是 unique_ptr
unique_ptr 代表的是专属所有权,即由 unique_ptr 管理的内存,只能被一个对象持有。
所以,unique_ptr 不支持复制和赋值,如下:

1
2
auto w = std::make_unique<Widget>();
auto w2 = w; // 编译错误

如果想要把 w 复制给 w2, 是不可以的。因为复制从语义上来说,两个对象将共享同一块内存。

因此,unique_ptr 只支持移动, 即如下:

1
2
auto w = std::make_unique<Widget>();
auto w2 = std::move(w); // w2 获得内存所有权,w 此时等于 nullptr

unique_ptr 代表的是专属所有权,如果想要把一个 unique_ptr 的内存交给另外一个 unique_ptr 对象管理。只能使用 std::move 转移当前对象的所有权。转移之后,当前对象不再持有此内存,新的对象将获得专属所有权。

如上代码中,将 w 对象的所有权转移给 w2 后,w 此时等于 nullptr,而 w2 获得了专属所有权。

转载自原文链接, 如需删除请联系管理员。

原文链接:c++智能指针总结,转载请注明来源!

0