智能指针
智能指针的智能,体现在智能指针能够在每次完成工作之后自动释放占用的空间。
我们通常使用的裸指针,使用完成后需要通过delete或者free来进行释放,那么如果我们没有进行释放操作,或者函数无法运行到释放操作的部分就已经在某些条件下退出了,该指针就会成为野指针。
例如:
int main()
{
int *a(new int);
if(1)
throw "-1";//或:return -1;
delete a;
return 0;
}
上述代码中,就是未运行到delete语句时,函数会在某种条件下退出函数栈,那么a就成了野指针,a所在的空间就会发生内存泄露。
还有一种情况,当用户希望用两个指针管理同一块内存时,使用拷贝构造默认的形式是浅拷贝,那么释放资源时就会出现两次释放同一块资源的错误,如果我们把它改成深拷贝,那么这两个指针就不再满足管理同一块内存的需求。
在C++中,我们使用智能指针来解决这样的问题。
智能指针,使用类来实现,利用对象出作用域自动调用析构函数的特性,来保证所占用内存的及时释放。
简单的智能指针模型可以这样写:
template<typename T>
class smartp
{
public:
smartp(T =T()) {}
~smartp() {delete _p;}
private:
T *_p;
};
不带计数的智能指针
- auto_ptr
转移对象的所有权。
也就是当我们使用一个auto_ptr(设为A)去拷贝构造或者给另一个auto_ptr(设为B)赋值的时候,原来的A就会变成空指针,因此,在auto_ptr的使用过程中,始终保证只用最后一个指针来管理资源。 - scoped_ptr
直接删除拷贝构造和赋值函数,也就是不允许使用拷贝构造或赋值运算来构造新的scoped_ptr指针。 - unique_ptr
同样的,unique_ptr也只使用最后一个指针来管理资源,并且它也删除了拷贝构造函数和赋值函数,取而代之的是带右值引用参数的拷贝构造和赋值。在使用的过程中,将被拷贝对象使用move强转成右值类型,然后调用对应的拷贝构造和赋值函数。
带引用计数的智能指针
给每一个对象资源匹配一个引用计数,使多个智能指针可以管理同一个资源。
计数减为0时释放资源。
- shared_ptr
可以改变资源的引用计数
定义对象的地方使用强智能指针。 - weak_ptr
不会改变资源的引用计数,用以解决强智能指针循环引用(交叉引用)时资源无法释放的问题。
应用智能指针的地方使用弱智能指针。