C++11智能指针

[C++11]智能指针

C++11包括了三种智能指针:

  1. shared_ptr
  2. weak_ptr
  3. unique_ptr

shared_ptr

shared_ptr是一个包装类,内部包装了真正的数据指针以及引用计数,当引用计数为0时自动释放指针,跟指针一样,重载了->操作符,也可以用*来进行解引用。
简单介绍

#include 
#include 
using namespace std;


int main(int /argc/, char const */argv/[])
{
    int *p = new int(2);

    /// 智能指针初始化/
    shared_ptr sp1(p);

    /// 不能构造指向相同数据的智能指针,否则p会被释放两次/
    /// shared_ptr sp2(p);/

    shared_ptr sp2 = sp1;
    shared_ptr sp3 = sp1;
    /// 三者的引用计数均为3/
    cout << sp1.use_count() << endl;
    cout << sp2.use_count() << endl;
    cout << sp3.use_count() << endl;

    /// 不声明指针的智能指针构造方法/
    shared_ptr sp4 = make_shared(2);
    shared_ptr sp5 = sp4;

    /// 引用计数为2/
    cout << sp4.use_count() << endl;
    cout << sp5.use_count() << endl;

    /// 重置sp4,引用计数变为1/
    sp4.reset();
    cout << sp4.use_count() << endl; /// 0/
    cout << sp5.use_count() << endl; /// 1/

    /// 重置sp4,sp4和sp5指向不同的数据/
    sp4.reset(new int(3));
    cout << sp4.use_count() << endl; /// 1/
    cout << sp5.use_count() << endl; /// 1/

    /// 判断智能指针是否为空/解引用智能指针/
    shared_ptr sp;
    if(!sp){
        cout << "sp is null" << endl;
    }
    sp.reset(new int(5));
    if(sp){
        cout << "sp is " << *sp << endl;
    }
    return 0;
}

shared_ptr构造类对象的智能指针

#include 
#include 
using namespace std;

class Foo{
    public:
    Foo(int /i/, int /j/){
        this->i = i;
        this->j = j;
    }
    void print(){cout << i << j << endl;}
    ~Foo(){
        cout << "destruct" << endl;
    }

    private:
    int i;
    int j;
};

int main(int /argc/, char const */argv/[])
{
    shared_ptr foo = make_shared(2,3);
    shared_ptr foo2 = foo;
    shared_ptr foo3 = foo2;
    cout << foo.use_count() << endl; /// 3/

    Foo* foo4 = foo.get(); /// 不会改变引用的计数/
    cout << foo.use_count() << endl; /// 3/
    foo4->print();

    foo2.reset();
    foo3.reset();
    foo.reset(); /// 调用析构/
    /// 如果注释掉foo的重置,析构函数会发生在打印“end of main"以后/
    cout << "End of main" << endl;
    return 0;
}

weak_ptr

简单来说,weak_ptr就是不能增加引用计数的智能指针,也没有重载*和->等符号的智能指针,但是weak_ptr::use_count()可以查看引用计数,也可以通过weak_ptr::expired查看是否过期。

#include 
#include 
using namespace std;

int main(int /argc/, char const */argv/[])
{
    weak_ptr wp0;
    cout << "wp0.expired() == " << std::boolalpha << wp0.expired() << endl; /// true/

    shared_ptr sp1(new int(5));
    weak_ptr wp1(sp1);
    cout << "wp1.expired() == " << std::boolalpha << wp1.expired() << endl; /// false/
    cout << "use count " << wp1.use_count() << endl; /// 1/
    return 0;
}

同时,weak_ptr还能通过lock方法来获取一个shared_ptr智能指针,在获取shared_ptr智能指针的时候会提升智能指针的引用计数

      shared_ptr sp2(new int(4));
    weak_ptr wp2(sp2);
    cout << "wp2.expired() == " << std::boolalpha << wp2.expired() << endl; /// false/
    cout << "use count " << wp2.use_count() << endl; /// 1/

    cout << "*wp2.lock() == "
            << *wp2.lock() << endl; /// 4/

    cout << "use count " << wp2.use_count() << endl; /// 1/
    shared_ptr sp3(wp2);
    shared_ptr sp4(wp2);
    /// 智能指针可以初始化多个shared_ptr,而普通指针不可以/
    cout << "use count " << wp2.use_count() << endl; /// 3/

unique_ptr

顾名思义,unique_ptr只能有一个,不能复制,只能通过move实现转移内部指针。

unique_ptrmyPtr(newT);//ok
unique_ptrotherPtr=myPtr;//编译错误

智能指针的应用场景

实现观察者模式

现在有一个设备模块,该模块从设备获取一条条数据(这里用Record表示一条数据),并通过观察者模式把Record分发给所有(观察了该数据的)观察者。观察者一般都是视图,如视图A得到数据后,通过表格显示数据的内容,而视图B上得到数据后,通过趋势图显示数据的内容。
当用户关闭了所有视图,意味没有视图再使用数据Record了,这时就可以释放掉Record;但是只要有一个视图在使用record,就不能释放Record。
如何管理Record的释放呢?这种情况使用智能指针,可以做到所有视图关闭后,自动释放Record。

工厂模式

假如你编写了一个工厂类,它提供一个接口,根据配置产生各种对象(内部调用new新建对象)。
由于该类很NewBee,它被封装为动态库提供给其他同事,当其他同事调用动态库得到新建对象后,新建对象将来由谁负责释放呢?如果没有统一且明确的沟通确认,很容易出现双方都忘记释放新建对象,或者同一个新建对象被双方都释放了一次的情况!
这时候你甩出了一个智能指针,然后宣布:大家都不用关心谁来释放了,让指针自己释放去吧。
::类对象应该让库释放还是让使用者释放一直很让人头疼::

避免代码发生异常时内存泄漏

void foo(){
        try{
            int *p = new int(0);
            do_something(p);
            delete p;
        }
        catch(...){
        }
    }

如果do_something函数中发生了异常,那么p就不会被释放,智能指针可以防止这种事情的发生

学习/c++

你可能感兴趣的:(C++11智能指针)