C++11:智能指针

一、什么是智能指针

在C++中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露。解决这个问题最有效的方法是使用智能指针(smart pointer)。 智能指针是存储指向动态分配(堆)对象指针的类,用于生存期的控制,能够确保在离开指针所在作用域时,自动地销毁动态分配的对象,防止内存泄露。随着C++的发展,有三个解决方案,一个方案对应着一种智能指针。

  • 将指针的管理权转移给另外一个对象。对应C++98的auto_ptr。
  • 防止拷贝。对应C++11的unique_ptr。
  • 引用计数。对应C++11的shared_ptr。

其实,C++一共提供了四种智能指针:auto_ptr, unique_ptr,shared_ptr,weak_ptr。其中后三个是C++11新增的,第一个由C++98提出,已经被C++11弃用。智能指针都包含在memory库中,要使用智能指针必须包含这个库。

二、auto_ptr

auto_ptr的原理是:将资源的管理权由一个对象转移给另外一个对象。但auto_ptr存在下面一些问题:

1、auto_ptr不能共享所有权

auto_ptr<int> p1(new int);
auto_ptr<int> p2(p1); // 拷贝
auto_ptr<int> p3;
p3 = p1; // 赋值

这样会导致p1,p2,p3同时指向p1内部的原始指针,由于每一个auto_ptr在被销毁的时候都会删除其所指向的对象,原始指针就会被重复删除3次,为了解决这个问题,要么禁用拷贝与赋值运算符,要么设计当auto_ptr拷贝或者赋值的时候对原始指针的所有权转移到新对象去。

2、auto_ptr不能指向数组

3、auto_ptr不能作为容器成员

4、auto_ptr不能通过赋值操作来初始化

std::auto_ptr<int> p = new int(42); // 错
std::auto_ptr<int> p(new int(42));  // 对

三、unique_ptr

unique_ptr可以看成是auto_ptr的替代品,用法如下:

1、不支持拷贝构造和赋值运算函数

unique_ptr<Obj> ap(new Obj);
unique_ptr one(ap);   // 会出错
unique_ptr two = one; // 会出错

2、可以移动构造和移动赋值操作

unique_ptr<Obj> Getobj();
{
     unique_ptr<Obj> ptr(new Obj);
     return ptr;
}
unique<Obj> ptr = Getobj;

unique_ptr<Obj> ptr1(new Obj());
unique_ptr<Obj> ptr2(std::move(ptr1));

四、shared_ptr

如果程序要使用多个指向同一个对象的指针,那么可以使用shared_ptr。基本使用方法如下:

shared_ptr <int> p1(new int(5));
shared_ptr<int> p2 = make_shared<int>(10);

int *pint = new int(10);

//shared_ptr<int>p3 = pint; //error
//p3 = pint; 				//error

use_count() //计数数量

unique() 	//是否只被一个使用

五、weak_ptr

shared_ptr是一种强引用关系,智能指针直接引用对象,代码会引起循环引用,从而造成内存泄漏。

  • weak_ptr用于配合shared_ptr使用,并不影响对象的生命周期,即存在与否并不影响对象的引用计数器。weak_ptr并没有重载operator-> 和operator* 操作符,因此不可直接通过weak_ptr使用对象。weak_ptr提供了expired()与lock()成员函数,前者用于判断weak_ptr指向的对象是否已被销毁,后者返回其所指对象shared_ptr智能指针(对象销毁时,返回空shared_ptr)。

  • weak_ptr被设计为shared_ptr共同工作,可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源观测权,但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。

  • 使用weak_ptr的use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价use_count()==0但更快,表示被观测资源(也就是shared_ptr管理的资源)已经不复存在。

  • weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象,从而操作资源,但当expired==true的时候,lock()函数将返回一个存储空指针的shared_ptr。

shared_ptr<int> spi1(new int(100));
shared_ptr<int> spi2(spi1);
weak_ptr<int> wp1 = spi1; 	 //观察spi1,不增加引用计数
cout<<wp1.use_count()<<endl; //观察,不能使用 *、->
cout<<wp1.expired() << endl; //观察,不能使用 *、->
auto spi1 = wp1.lock();
if(spi) {
	cout<<*spi<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值