c++11中常用的智能指针有shared_ptr
,unique_ptr
与weak_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指针,保证了安全性。