智能指针
在C++中,如果指针使用不当,比如没有及时释放指针所指向的内存,或者野指针等,会造成系统发生不可预估的错误,为了防止这一情况的发生,C++ STL提供了一系列智能指针类型
智能指针简单来说就是系统会帮助我们进行管理,并及时释放占用的内存,简单结构如下
template<class T>
class Smart_Pointer {
private:
T *_ptr;
public:
Smart_Pointer(T* ptr):_ptr{ptr}
{}
~Smart_Pointer()
{
delete _ptr;
_ptr = nullptr;
}
T& operator*() { //为什么不能重载.?因为.不能被重载.且对象是一个指针,使用方式是(*P).xxxx()或者p->xxxx()
return *_ptr;
}
T* operator->() {
return _ptr;
}
};
C++11 STL提供了三种常用只能指针,分别是:
unique_ptr
Shared_ptr
Weak_ptr;
Shared_ptr:
智能指针shared_ptr允许多个指针指向同一个对象;unique_ptr则”独占”所指向的对象
类似vector,只能指针也是模板,需要提供相关的类型
Shared_ptr<string> p1 //可以指向string的智能指针类型
默认初始化的智能指针保存着一个空指针,同时我们可以通过make_shared来初始化指针
这是最安全的分配和使用动态内存的方法,此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr
Shared_ptr<int> p3 = make_shared<int>(42); //调用构造函数
//指向一个值为42的int的shared_ptr
我们可以认为每个shared_ptr都有一个关联的计数器,通常称为引用计数,
当我们将一个ptr作为参数传递给另一个ptr,或是初始化,或是作为函数返回值: 比如复制操作:auto p4(p3);
它的引用计数器就会加一。
当赋予一个新值或是被销毁,就会进行递减,比如r和q是两个shared_ptr
如r = q; 给r赋予q的地址,r的原地址销毁,引用计数器减一,q加一 ,
我们可以通过use_count()函数来查看引用计数情况:
spI1.use_count()
Shared_ptr 自动销毁所管理的对象
当指向一个对象的最后一个shared_ptr被销毁以后,shared_ptr类会自动销毁此类对象。它是通过另一个特殊成员函数—析构函数完成销毁工作的(当引用计数变为0后,就自动销毁了)
Unique_ptr:
unique_ptr独享所有权,一个非空的std::unique_ptr总是拥有它所指向的资源
转移一个std::unique_ptr也会把源指针转移给目标指针
为了防止指向相同资源,拷贝是不被允许的
unique_ptr<int[]> pI1(new int[5]{ 1,2,3,4,5 });
cout << pI1[3] << endl;
auto PI2 = move(pI1); //不可被复制,只能通过move右值引用
由于unique_ptr不能拷贝,因此我们只能使用move()进行传值
weak_ptr
Weak_ptr是为了配合shared_ptr而引入的一种智能指针
它更像是shared_ptr的一个助手而非智能指针,因为它不具有普通指针的行为
它获得观测权但不占用资源,它的构造不会引起引用计数的增加
weak_ptr<int> wpI1 = spI1;
wpI1.use_count() //并没有引起计数器的增加
同时weak_ptr提供lock()函数来判断shared_ptr是否存在,如果存在,weak_ptr返回一个指向共享对象的shared_ptr,否则返回空指针
if(shared_ptr<int> np = wpI1.lock())
{
//在if中,np与wpI1共享对象
}
智能指针的释放:
spI1.reset();
还没有评论,来说两句吧...