Skip to main content

C++的智能指针

智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏

为什么要用智能指针

如果申请的空间在函数结束时忘记释放,则会造成内存泄漏。使用智能指针可以很大程度上的避免这个问题,因为智能指针是一个类,当超出了类的实例对象的作用域时,会自动调用对象的析构函数,析构函数会自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间

auro_ptr

auro_ptrC++98中的智能指针方案,采用所有权模式,但在C++11中被弃用

auto_ptr<string> p1 (new string ("hello world")); 
auto_ptr<string> p2;
p2 = p1;

p2剥夺了p1的所有权,程序访问p2时不会报错,但是访问p1时程序会报错,auto_ptr仍存在内存泄漏的问题。

unique_ptr

(替换auto_ptr)unique_ptr 用于不能被多个实例共享(独占)的内存管理。就是说仅有一个实例拥有内存所有权,保证同一时间内只有一个智能指针指向一个对象,对于避免内存泄露非常有效

unique_ptr<string> p1 (new string ("hello world")); 
unique_ptr<string> p2;
p2 = p1; // 编译时将会报错

当把一个unique_ptr赋值给另一个时,如果unique_ptr是一个临时右值,将会被允许操作

unique_ptr<string> p;
p = unique_ptr<string>(new string("hello world")); // 编译通过

这里调用unique_ptr的构造函数,当将构造函数创建的临时变量的所有权转让给p之后就会销毁

  • unique_ptr相比起auro_ptr更加的安全
tip

标准库STL提供了一种方法std::move()可以将一个unique_ptr赋值给另一个,也就是转移所有权,使用这个语法时你应该明白是在干什么,而不是在胡乱使用指针

shared_ptr

shared_ptr 实现共享式概念。多个智能指针可以指向相同的对象,这个对象和其相关的资源会在最后一个引用被释放的时候才会释放。

shared_ptr 使用计数机制来实现指针的共享,可以通过use_count()方法来查看指针个数。

除了使用 new 构造之外,还可以通过传入,auto_ptr、unique_ptr、weak_ptr 来构造,当调用release()方法时,当前指针会释放资源所有权,计数值减一,当计数值为零时,则释放资源。

shared_ptr 中的一些方法

方法描述
use_count()返回引用计数的个数
unique()返回是否独占所有权,即计数为1
swap()交换所拥有的对象
get()返回内部对象(指针)
reset()放弃内部对象的所有权或者拥有对象的变更,会引起原有对象的引用技术减少

shared_ptr相比于auto_ptr已经解决了很多的问题,但是当两个shared_ptr互相指向对方(循环引用),指针计数个数不会降为零,资源将一直不会被释放,导致内存泄漏,为了解决这个问题,又引入了 weak_ptr

weak_ptr

weak_ptr是指向一个shared_ptr管理的对象

weak_ptr最初设计的目的是用来辅助shared_ptr工作,属于对对象的弱引用,构造时不会增加引用计数

weak_ptrshared_ptr之间可以互相转化

  • shared_ptr可以直接赋值给它
  • weak_ptr可以调用lock函数来获得shared_ptr
方法描述
expired ()检测所管理的对象是否已经释放,已经释放返回true否则返回false
lock()获取所管理的对象的shared_ptr,如果expired()true,则返回一个空的shared_ptr
use_count()返回shared_ptr共享的对象的引用计数
reset()放弃内部对象的所有权或者拥有对象的变更,会引起原有对象的引用技术减少

reference