c++ 智能指针std::shared_ptr

发布时间 2023-06-01 11:46:43作者: _Explosion!

c++11中常用的智能指针有shared_ptrunique_ptrweak_ptr。

unique_ptr是独占型指针,其计数永远为1,无拷贝构造函数,但可以使用std::move转移资源所有权。

weak_ptr没有资源所有权,一般用来辅助shared_ptr使用,多使用于多线程,循环等场景。

shared_ptr可以多个指针绑定同一对象,同一堆空间每多一个shared_ptr指向该空间,计数就+1。计数为0时析构。

可以使用get()方法获得智能指针的原始指针。

可以使用reset()方法改变智能指针的指向,并使其原本的计数-1。

需注意,使用shared_ptr时,应避免用裸指针去初始化shared_ptr,因为同一裸指针初始化多个shared_ptr会导致该多个shared_ptr的计数器均为1(即各个shared_ptr的分组不同),会导致重复析构。

可以使用make_shared或直接用new的右值去初始化shared_ptr。

atuo p=new A();
std::shared_ptr<A> sp1(p);     //避免使用
std::shared_ptr<A> sp2(p);     //不同分组!
std::shared_ptr<A> sp3(sp1.get());    //不同分组!
//以下为常用初始化方法
std::shared_ptr<A> sp1(new A());
std::shared_ptr<A> sp1 = make_shared<A>();

当遇到需要在类中返回一个当前对象的shared_ptr,不能直接retrun shared_ptr(this),因为这种方法同样也是类似裸指针初始化,会导致重复析构。

可以将有该需求的类变成std::enable_shared_from_this模板对象的派生类,从而可以使用shared_from_this()方法安全的返回一个shared_ptr。

class A : public std::enable_shared_from_this<A>
{
public:
    A()
    {
        std::cout << "A constructor" << std::endl;
    }
​
    ~A()
    {
        std::cout << "A destructor" << std::endl;
    }
​
    shared_ptr<Object> func(int key){
        shared_ptr<Object> shObject;
        shObject.reset(new Object(key), boost::bind(& A::cbDelete,shared_from_this(), _1));    //此处使用shared_from_this()
        return shObject;
    }
private:
    void cbDelete(Object* obj){
        ....
        delete obj;
    }
};

观察上例可看到在func函数中,需要将shObject用reset将其指向new得到的Object对象,同时给了reset函数的第二个参数,绑定了一个回调函数让其析构时执行。而该绑定需要本对象的this指针,此处使用了shared_from_this()函数而非直接传递this指针,保证了安全性。