智能指针
shared_ptr类
\(与vector类似,智能指针也是模板.\)
shared_ptr<string> p1;
shared_pte<list<int>> p2;
\(默认初始化的智能指针是一个空指针,与普通指针一样,解引用得到它指向的对象.\)
if (p && p->empty())
*p = "hi" // p的类型shared_str<string>
shared_ptr 和 unqiue_ptr 的共有操作 :
shared_ptr<T> sp // 空指针
unique_ptr<T> up
p // 可作为条件语句, 若指向一个对象, 则为true
*p
p->men
p.get() // 返回p保存的指针
swap(p, q)
shared_ptr 独有 :
make_shared<T>(arg) // 返回一个shared_ptr,指向一个动态分配的类型T, arg初始化
shared_ptr<T> p(q) // 拷贝, 此操作递增q的计数器.
p = q; // 递增q的计数器, 递减p的计数器
p.use_count() // 返回计数器
p.unique() // 计数器为1,则为true
make_shared 函数
\(最安全的分配和使用动态内存方式\)
\(返回shared\_ptr\)
\(模板,使用时,再函数名后跟尖括号,给出类型.\)
shared_ptr<int> p3 = make_shared<int> (42); // 指向一个值为42的int
shared_ptr<string> p4 = make_shared<string> (10, '9') // 指向一个string
shared_ptr<int> p5 = make_shared<int> (); // 指向一个初始化为0的int
shared_ptr<string> p6 = make_shared<string> () // 指向一个空string
shared_ptr 的拷贝和赋值
\(每个shared\_ptr都会记录有都多少个其他shared\_ptr指向相同的对象\)
auto p = make_shared<int> (42) // p 所指对象只有一个引用者
auto q(p); // 有了两个引用者
\(拷贝计数计递增\)
\(当给shared\_ptr赋一个新值或者被销毁时(例如局部的shared\_ptr离开其作用域)\\计数器递减.\)
\(一旦一个shared\_ptr的计数器为0,它就会自动释放自已所管理的对象:\)
auto r = make_shared<int> (42); // r 指向的int只有一个引用者
r = q; // 递增q指向对象的引用计数
// 递减r原来指向的对象的引用计数
// r原来指向的对象已没有引用者,自动释放
shared_ptr 自动销毁所管理的对象
\(当指向一个对象的最后一个shared\_ptr被销毁时,shared\_ptr类会自动销毁此对象.\\它是通过析构函数完成销毁工作的.\)
\(shared\_ptr的析构函数会递增它所指的对象的引用计数,如果计数变为0,\\shared\_ptr的析构函数就会销毁对象,释放它占用的内存.\)
unique_ptr类
\(与shared\_ptr不同,某个时刻只能有一个unique\_ptr指向一个给定对象.\)
\(它没有类似make\_shared的函数返回一个unique\_ptr.所以需要定义时,需将其绑定到一个new返回的指针上.\\与shared\_ptr一样,必须采用直接初始化的方式.\)
unique_ptr<double> p1;
unique_ptr<int> p2(new int(42));
\(由于同一时刻只有一个unque\_ptr指向一个对象,因此不支持普通拷贝与赋值.\)
unique_ptr<string> p1(new string("abc"));
unique_ptr<string> p2(p1) // 错误:不支持拷贝
unique_ptr<string> p3;
p3 = p2; // 错误:不支持赋值
unique_ptr 操作:
u.release() // u放弃对指针的控制,返回指针,并将u置空
u.reset() // 释放u指向的对象
u.reset(q) // 如果提供了内置指针q,令u指向这个对象,否则将u置空
u.reset(nullptr)
\(虽然不能拷贝或赋值unique\_ptr,但可以通过release或reset将指针的所有权从一个(非const)unique\_ptr转移给令一个unique:\)
unique_ptr<string> p2(p1.release());
unique_ptr<string> p3(new string("Trex"));
p2.reset(p3.release());