【C++ Primer】
shared_ptr:
除了make_shared那种方法(make_shared更好),还可以用new返回的指针来初始化智能指针,例如shared_ptr<int> p (new int(42)); 但是我们不能将一个内置指针隐式转换为一个智能指针,必须使用直接初始化形式来初始化一个智能指针,例如shared_ptr<int> p1 = new int(1024); 这种方法就是错误的,不可以进行内置指针到智能指针之间的隐式转换。
reset函数有三种,p.reset(),p.reset(q),p.reset(q, d)。如果p是唯一指向其对象的shared_ptr,那么reset会释放此对象。如果传递了一个内置指针q,会令p指向q,否则会将p置为空。若还传递了参数d,将会调用d而不是delete来释放q。前面说了不能将一个内置指针赋予shared_ptr,但用reset将一个新的指针赋予一个shared_ptr是可以的,比如p.reset(new int(1024));
不要混用普通指针和智能指针,使用一个内置指针来访问一个智能指针所负责的对象是很危险的,因为我们不知道对象何时会被销毁。
unique_ptr:
某个时刻只能有一个unique_ptr指向一个给定对象,当unique_ptr被销毁时,它所指向的对象也被销毁。定义方法:unique_ptr<int> p2(new int(42)); 要采用直接初始化形式。
u.release()表示u放弃对指针的控制权,返回指针,并将u置为空。
u.reset()表示释放u指向的对象,如果提供了内置指针如u.reset(q),则令u指向这个对象,否则将u置为空。虽然我们不能拷贝或赋值unique_ptr,但可以通过调用release或reset将指针的所有权从一个(非const)unique_ptr转移给另一个unique_ptr,例如:
unique_ptr<string> p1(new string("hello"));
unique_ptr<string> p2(p1.release()); // release将p1置为空,然后将原本p1对指针(指向"hello")的所有权转移给p2
unique_ptr<string> p3(new string("hi"));
p2.reset(p3.release()); // reset释放了p2原来指向的对象(也就是"hello"),然后把p3对指针(指向"hi")的所有权转移给p2
weak_ptr:
是一种不控制所指对象生存期的智能指针,它指向一个shared_ptr管理的对象。创建一个weak_ptr时是用一个shared_ptr来初始化它,创建的weak_ptr不会改变shared_ptr的引用计数,weak_ptr指向的对象可能被释放掉。由于对象可能不存在,所以我们不能使用weak_ptr直接访问对象,而必须调用lock(),此函数检查weak_ptr指向的对象是否仍存在,如存在,返回一个指向共享对象的shared_ptr。