智能指针

匿名 (未验证) 提交于 2019-12-03 00:33:02

C++98中的智能指针通过一个模板类auto_ptr来实现,new操作符返回的指针可以交由它来管理,程序员不用再显式的调用delete,这在一定程度上避免了堆内存忘记释放的问题;不过auto_ptr有一些缺点,比如拷贝时返回一个左值,不能调用delete[]等

C++11中废弃了auto_ptr,改用unique_ptr、shared_ptr、weak_ptr等智能指针来自动回收堆分配对象,使内存管理更安全,智能指针的使用场景也变得更全面。

unique_ptr是唯一性智能指针,无法进行复制,但是可以移动。而shared_ptr是共享性智能指针,采用引用计数,可以拷贝和移动,移动时引用计数不会变化。

Example

 #include <memory> #include <iostream> using namespace std;  int main() {     unique_ptr<int> up1(new int(11));             unique_ptr<int> up2 = up1;        //不能通过编译      cout << *up1 << endl;                //11     unique_ptr<int> up3 = move(up1);    //现在p3是数据唯一的unique_ptr智能指针      cout << *up3 << endl;                //11     cout << *up1 << endl;                //运行时错误     up3.reset();                        //显式释放内存     up1.reset();                        //不会导致运行时错误     cout << *up3 << endl;                //运行时错误      shared_ptr<int> sp1(new int(22));     shared_ptr<int> sp2 = sp1;      cout << *sp1 << endl;    //22     cout << *sp2 << endl;    //22      sp1.reset();     cout << *sp2 << endl;    //22 }  //编译选项:g++ -std=c++11 unique_share.cpp

上例中,指针调用reset成员时,智能指针都可能释放其拥有的堆内存。

从代码中可以看出,unique_ptr和shared_ptr在对所占内存的共享上还是有一定区别的。

unique_ptr不能与其他unique_ptr类型的指针共享所指对象的内存。比如unique_ptr

而shared_ptr允许多个智能指针共享地“拥有”同一堆分配对象的内存。与unique_ptr不同的是,一旦一个shared_ptr指针放弃了“所有权”,其他的shared_ptr对对象内存的引用并不会受到影响。上例中的sp2很好说明了这个状况,sp1调用了reset成员,只是使得引用计数的降低,不会导致堆内存的释放。只有在引用计数归零时,shared_ptr才会真正地释放所占有的堆内存的空间。

weak_ptr

弱智能指针,通常指向一个共享性智能指针,当要使用所指向的共享性智能指针时,使用lock方法获取,并验证共享性智能指针的有效性。

Example:

#include <memory> #include <iostream> using namespace std;  void Check(weak_ptr<int> &wp) {     shared_ptr<int> sp = wp.lock();    //转换为shared_ptr<int>     if (sp != nullptr)         cout << "still " << *sp << endl;     else         cout << "pointer is invalid." << endl; }  int main() {     shared_ptr<int> sp1(new int(22));     shared_ptr<int> sp2 = sp1;     weak_ptr<int> wp = sp1;    //指向shared_ptr<int>所指对象      cout << *sp1 << endl;    //22     cout << *sp2 << endl;    //22     Check(wp);                //still 22      sp1.reset();                 cout << *sp2 << endl;    //22     Check(wp);                //still 22      sp2.reset();     Check(wp);                //pointer is invalid      return 0; }  //编译选项:g++ -std=c++11 weak.cpp

上例中定义了2个shared_ptr――sp1和sp2,而weak_ptr wp同样指向该对象内存。当sp1和sp2有效时,调用wp的lock(),check会输出still 22。当分别调用sp1和sp2的reset()时,会导致堆内存对象的引用计数降为0。一旦引用计数归0,shared_ptr

整个过程中,只有shared_ptr参与了引用计数,而weak_ptr没有影响其指向的内存的引用计数。因此可以验证shared_ptr指针的有效性。

简单情况下,程序员用unique_ptr代替以前使用auto_ptr就可以使用C++11中的智能指针。而shared_ptr及weak_ptr则可用在用户需要引用计数的地方。

原文:https://www.cnblogs.com/Stephen-Qin/p/9217620.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!