C++11智能指针

智能指针 unique_ptr shared_ptr weak_ptr


在C98中,智能指针通过一个模板类型"auto_ptr"来实现。auto_ptr以对象的方式管理分配的内存,并在适当的事件(比如析构),放释所获得的堆内存。这种对内存管理的方式只需要程序员将new操作返回的指针作为auto_ptr的初始值即可,程序员不用再显示地调用delete,比如:

  auto_ptr(new int);

不过auto_ptr也有一些缺点(拷贝时返回一个左值,不能调用delete[]等);


  • shared_ptr
    shared_ptr允许多个该智能指针共享的"拥有"同一堆分配对象的内存,与unipue_ptr不同的是,由于在实现上采用了引用技术,所以一旦一个shared_ptr指针放弃了"所有权",其他的shared_ptr对对象内存的引用并不会收到影响。只有在引用技术归零的时候,shared_ptr才会真正释放所占有的堆内存空间。
#include<iostream>
#include<memory>
using namespace std;

int main()
{
    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
        return 0;
}

  • unique_ptr
    unique_ptr与所指对象的内存绑定紧密,不能与其他unique_ptr类型的指针共享所指对象的内存,因为每个unique_ptr都是唯一的"拥有"所指向的对象内存。这种"所有权"仅能通过标准库的move函数来转移,一旦"所有权"转移成功了,原来的unique_ptr指针就失去了对象内存的所有权,此时在使用已经没有内存所有权的指针就会导致运行时错误!!!
#include<iostream>
#include<memory>
using namespace std;

int main()
{
    unique_ptr<int> up1(new int(11));   //无法复制的unique_ptr
    //unique_ptr<int> up2 = up1;        //不能通过编译
    cout << *up1 << endl;               //11


    unique_ptr<int> up3 = move(up1);    //转移up1的内存所有权到up3
    cout << *up3 << endl;
    //cout << *up1 << endl;             //运行出错

    up3.reset();                        //显示释放内存
    up1.reset();                        //不会导致运行时错误
    cout << *up3 << endl;               //运行错误

  return 0;
}

  • weak_ptr
    weak_ptr可以指向shared_ptr指针指向的对象内存,但却不拥有该内存,而使用weak_ptr成员lock,则可以返回其指向内存的一个shared_ptr对象,且在所指对象内存已经无效时,返回空指针,这在验证shared_ptr指针的有效性上会很有用。
#include<iostream>
#include<memory>
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所指对象

    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;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容