智能指针
智能指针是为了避免内存泄漏的技术。
智能指针采用了RAII特性,利用对象生命周期来控制程序资源 ,在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。 这么做有两大好处:
1.不需要显式地释放资源
2.采用这种方式,对象所需的资源在其生命期内始终保持有效 。
C++的智能指针都在下边这个头文件中
#include <memory>
智能指针类模拟实现:
template<class T>
class SmartPtr {
public:
SmartPtr(T* ptr = nullptr)
: _ptr(ptr)
{}
~SmartPtr()
{
if(_ptr)
delete _ptr;
}
T& operator*() {
return *_ptr;
}
T* operator->() {
return _ptr;
}
private:
T* _ptr;
};
int main()
{
SmartPtr<int> sp1(new int);
*sp1 = 10
cout<<*sp1<<endl;
return 0;
}
注意:智能指针需要重载operator*和opertaor->,具有像指针一样的行为 。
std::auto_ptr
当auto_ptr指针对对象拷贝或者赋值后,被拷贝的对象就悬空了,它的资源被释放了。(所以auto_ptr不怎么用)
std::unique_ptr
unique_ptr就是用来防拷贝,也就是不让拷贝和赋值 。
C++98防拷贝的方式:只声明不实现+声明成私有
private:
UniquePtr(UniquePtr<T> const &);
UniquePtr & operator=(UniquePtr<T> const &);
C++11把赋值拷贝函数delete就行了
UniquePtr(UniquePtr<T> const &) = delete;
UniquePtr & operator=(UniquePtr<T> const &) = delete;
std::shared_ptr
shared_ptr通过引用计数支持智能指针对象的拷贝
实现原理:
1.shared_ptr在其内部,给每个资源都维护了着一份计数,用来记录该份资源被几个对象共享
2.在对象被销毁时(也就是析构函数调用),就说明自己不使用该资源了,对象的引用计数减一
3.如果引用计数是0,就说明自己是最后一个使用该资源的对象,必须释放该资源
4.如果不是0,就说明除了自己还有其他对象在使用该份资源,不能释放该资源,否则其他对象就成野指
针了 .
shared_ptr的实现
shared_ptr的循环引用问题:使用weak_ptr协助shared_ptr解决。
weak_ptr
1.它没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。
2.weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。
3.但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count()==0,但更快,表示被观测的资源(也就是shared_ptr的管理的资源)已经不复存在。
4.weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象, 从而操作资源。但当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr。