C++:智能指针

auto_ptr

auto_ptr是C++标准库中为了解决资源泄露的问题提供的一个智能指针模板,是一种简单的智能指针
功能:动态分配对象以及当对象不再需要时自动执行清理
实现原理:在构造的时候获取资源,在析构的时候释放资源,并进行相关指针操作的重载,使用起来和普通指针类似,但由于其构造函数声明为explicit,因此不能通过隐式转换来构造,只能显示调用构造函数

auto_ptr<string> pstr(new string("abc")); // succeess
auto_ptr<string> pstr = new string("abc"); // error

特性及注意事项:
①auto_ptr没有考虑引用计数,因此一个对象只能由一个auto_ptr所拥有,在给其他auto_ptr赋值,参数传递的时候,会转移这种拥有关系
②使用auto_ptr作为成员变量,取代普通指针,以避免资源泄漏。防止构造函数产生了异常,导致析构函数不会调用。
③auto_ptr不能共享所有权
④auto_ptr不能指向数组,因为数组在析构的时候需要调用delete[],而它只会调用delete
⑤auto_ptr不能作为容器对象,防止在进行拷贝、赋值等操作时,传递所有权

属于memory头文件,需#include

unique_ptr

unique_ptr独占所指向的对象,同一时刻只能有一个,它只能移动。由于每个unique_ptr对象都是原始指针的唯一所有者,因此在其析构函数中它直接删除关联的指针,不需要任何参考计数

unique_ptr具有->和*运算符重载符,因此它可以像普通指针一样使用

unique_ptr 指向给定对象,定义于memory中,命名空间为std

unique_ptr 不支持拷贝和赋值.

shared_ptr

shared_ptr 是一个标准的共享所有权的智能指针, 允许多个指针指向同一个对象. 定义在 memory 文件中(非memory.h), 命名空间为 std

shared_ptr 是为了解决 auto_ptr 在对象所有权上的局限性(auto_ptr 是独占的), 在使用引用计数的机制上提供了可以共享所有权的智能指针, 当然这需要额外的开销

shared_ptr 对象除了包括一个所拥有对象的指针外, 还必须包括一个引用计数代理对象的指针

时间上的开销主要在初始化和拷贝操作上, *和->操作符重载的开销跟auto_ptr是一样

开销并不是我们不使用shared_ptr的理由, 永远不要进行不成熟的优化, 直到性能分析器告诉你这一点

share_ptr使用注意事项:
(1)、不要把一个原生指针给多个shared_ptr管理;

(2)、不要把this指针给shared_ptr;

(3)、不要在函数实参里创建shared_ptr;

(4)、不要不加思考地把指针替换为shared_ptr来防止内存泄漏,shared_ptr并不是万能的,而且使用它们的话也是需要一定的开销的;

(5)、环状的链式结构shared_ptr将会导致内存泄漏(可以结合weak_ptr来解决);

(6)、共享拥有权的对象一般比限定作用域的对象生存更久,从而将导致更高的平均资源使用时间;

(7)、在多线程环境中使用共享指针的代价非常大,这是因为你需要避免关于引用计数的数据竞争;

(8)、共享对象的析构器不会在预期的时间执行;

(9)、不使用相同的内置指针值初始化(或reset)多个智能指针;

(10)、不delete get()返回的指针;

(11)、不使用get()初始化或reset另一个智能指针;

(12)、如果使用get()返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了;

(13)、如果你使用智能指针管理的资源不是new分配的内存,记住传递给它一个删除器。

weak_ptr

weak_ptr 也是以模板类的方式实现的. 定义在 memory 文件中(非memory.h), 命名空间为 std

weak_ptr是弱智能指针对象,它不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的智能指针。所以weak_ptr通常不单独使用(没有实际用处),只能配合shared_ptr类型指针搭配使用,同时也不影响所指对象被释放

借助weak_ptr类型指针,我们可以获取shared_ptr指针的一些状态信息,比如有多少指向相同的shared_ptr指针、shared_ptr指针指向的堆内存是否已经被释放等

weak_ptr模板类中没有重载*和->运算符,所以weak_ptr类型指针只能访问所指的堆内存,而无法修改它

scoped_ptr

scoped_ptr与auto_ptr类似,包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确删除。但最大的区别就是它不能转让管理权,即scoped_ptr禁止用户进行拷贝与赋值

实现方法:将拷贝构造函数与赋值运算符重载的访问限定符设置为private,并且只给出其声明:

class ScopedPtr{
private:
    ScopedPtr(const ScopedPtr& sp);
    ScopedPtr& operator(const ScopedPtr& sp);  
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值