c++智能指针详解
动态内存
每个程序有一个内存池,称为堆,用于存储动态分配的对象,即那些在程序运行时分配的对象。动态对象的生存周期由程序来控制,也就是说,当动态对象不再使用时,我们的代码必须显示的销毁他们。
使用懂态内存是十分必要的额,但众所周知,正确管理动态内存是十分棘手的。比如忘记释放内存就会产生内存泄漏。有时尚有指针引用指向内存但被释放了,就会产生野指针。因此产生了智能指针。c++11提供了三种包括:shared_ptr,unique_ptr,weak_ptr.
shared_ptr详解
所用到的技术就是引用技术,引用计数关联到具体的object。当指向这个object的shared_ptr增加时,引用计数自加,减少时,引用计数减少。当引用技术为0时释放改object。引用计数自增发生在初始化,赋值时。自减发生在赋值,析构时。
shared_ptr<T> sp; 空智能指针。
constexpr shared_ptr(nullptr_t) : shared_ptr() {}
template <class U> explicit shared_ptr (U* p) 不支持隐式转换。
template <class U> shared_ptr (const shared_ptr<U>& x) noexcept;
template <class U> shared_ptr (shared_ptr<U>&& x) noexcept;
template <class U> shared_ptr& operator= (const shared_ptr<U>& x) noexcept;
template <class U> shared_ptr& operator= (shared_ptr<U>&& x) noexcept;
p 用p作为一个条件判断,若p指向一个对象则为true。
*p 解引用p,获得它指向的对象
p->men 等价于(*p).men
p.get() 返回p中保存的指针
swap(p,q) 交换p,q中的指针
p.swap(q)
make_shared<T>(args) 返回一个shared_ptr,指向一个动态分配的类型为T的对象,用args初始化。
shared_ptr<T>p(q)
p=q
p.unique() 若p.use_count()为1,返回true,否则返回false。
p.use_count() 返回p共享对象的智能指针数量,用于调试。
当第一个智能指针被创建,唯一来源通过shared_ptr<T> p(new T); 或 shared_ptr<T> p=make_shared<T>();。另外一种情况T* p=new T;shared_ptr<T> q(p);这种会产生野指针,故不应这么写。第一个智能指针,通过拷贝构造,拷贝赋值(或被其他智能指针赋值的此类智能指针)所衍生出来的智能指针共享一个引用计数。成员函数get不应通过获得的指针进行释放,初始化一个智能指针。
unique_ptr
某个时刻只能有一个unique_ptr指向一个给定对象。当unique_ptr被销毁时,它所指向的对象也被销毁了。
与shanred_ptr不同,没有类似make_shared的表标准库返回一个unique_ptr.当我们定义一个unique_ptr时,需要其绑定一个new返回的指针上。此种初始化方式为显示的。
由于一个unique_ptr拥有它指向的对象,因此unique_ptr不支持普通的拷贝或复制操作。