struct X {int a;}; shared_ptr<X> px(new X); shared_ptr<int> pi(px, &px->a); // X owns a. 创建指向a的指针需要保证其所在X存在,所以用aliasing constructor。
一个错误示例:TODO
1 2 3 4
shared_ptr<X> sp1(new X); shared_ptr<X> sp2(sp1, new X); // ERROR: delete for this X will never be called sp1.reset(); // deletes first X; makes sp1 empty shared_ptr<X> sp3(sp1, newX); // use_count()==0, but get()!=nullptr
用make_shared<X>(...)比较好。
使用cast:
1 2
shared_ptr<void> sp(newint); // shared pointer holds a void* internally static_pointer_cast<int*>(sp); // OK
Class weak_ptr in Detail
share an object without owing it.
定义:
1 2 3 4 5 6 7 8 9
namespacestd { template <typename T> class weak_ptr { public: typedef T element_type; ... } }
// create and initialize (pointer to) string: std::unique_ptr<std::string> up(newstd::string("nico")); (*up)[0] = 'N'; // replace first character up->append("lai"); // append some characters std::cout << *up << std::endl; // print whole string
但是没有指针算术如++之类的操作。可以是空的即不持有一个对象。
1 2 3
std::unique_ptr<std::string> up; up = nullptr; up.reset();
用release来把所有权交出。
1 2
std::unique_ptr<std::string> up(newstd::string("nico")); std::string* sp = up.release(); // up loses ownership
检查unique_ptr是否为空。
1 2 3
if (up) {} // if up is not empty if (up != nullptr) {} // if up is not empty if (up.get() != nullptr){} // if up is not empty
Transfer of Ownership by unique_ptr
程序员需要保证从同一个普通指针初始化的unique_ptr只有一个。
1 2 3
std::string *sp = newstd::string("hello"); std::unique_ptr<std::string> up1(sp); std::unique_ptr<std::string> up2(sp); // RUNTIME ERROR: up1 and up2 own same data
如果要转移,应用C++11的move。如果被转移的unique_ptr之前指向别人,别人被删除。
1 2 3 4 5 6 7 8
// initialize a unique_ptr with a new object std::unique_ptr<ClassA> up1(new ClassA); // transfer ownership of the unique_ptr std::unique_ptr<ClassA> up2(std::move(up1)); // delete old object and own new up2 = std::unique_ptr<ClassA>(new ClassA); // delete the associated object up2 = nullptr;
std::unique_ptr<ClassA> source() { std::unique_ptr<ClassA> ptr(new ClassA); // ptr owns the new object ... return ptr; // transfer ownership to calling function } voidg() { std::unique_ptr<ClassA> p; for (int i = 0; i < 10; ++i) { p = source(); // p gets ownership of the returned object (previously returned object of f() gets deleted) } }
namespacestd { // primary template: template <typename T, typename D = default_delete<T>> classunique_ptr { public: typedef ... pointer; // may be D::pointer typedef T element_type; typedef D deleter_type; ... T& operator*() const; T* operator->() constnoexcept; ... }; // partial specialization for arrays: template<typename T, typename D> classunique_ptr<T[], D> { public: typedef ... pointer; // may be D::pointer typedef T element_type; typedef D deleter_type; ... T& operator[](size_t i) const; ... } }
其中变量是一个pointer和一个deleter的构造函数重载多个。TODO
1 2 3 4 5
D d; //instance of the deleter type unique_ptr<int, D> p1(newint, D()); // D must be MoveConstructible unique_ptr<int, D> p2(newint, d); // D must be CopyConstructible unique_ptr<int, D&> p3(newint, d); // p3 holds a reference to d unique_ptr<int, const D&> p4(newint, D()); //Error: rvalue deleter object, can’t have reference deleter type