auto_ptr

  auto_ptr是当前C++标准库中提供的一种智能指针。

  auto_ptr在构造时获取某个对象的所有去(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性:

int* p = new int();
auto_ptr<int> ap(p);

  从此我们不必关心应该何时释放p,也不必担心发生异常会有内存泄漏,这是因为auto_ptr的析构函数会执行指针的释放,而析构函数会在ap除了作用域以后执行。

  auto_ptr的出现,主要是为了解决“被异常抛出时发生资源泄漏”的问题。即如果我们让资源在局部对象构造时分配,在局部对象析构时释放,这样即使在函数执行过程时发生异常退出,也能保证局部对象被析构从而保证资源被释放。

  这里我们只有几点要注意:  

  1)因为auto_ptr析构的时候肯定会删除它所拥有的那个对象,所以两个auto_ptr不能同时拥有一个对象。像这样:

int* p = new int();
auto_ptr<int> ap1(p);
auto_ptr<int> ap2(p);

  因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p,两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr

  2)考虑下面这样用法

int* pa = new int[];
auto_ptr<int> ap(pa);

  因为auto_ptr的析构函数中删除指针用的是delete,而不是delete[],所以我们不应该用auto_ptr来管理一个数组指针。

  与引用计数型智能指针不同的,auto_ptr要求对其“裸”指针的完全占用性。也就是说一个“裸“指针不能同时被两个以上的auto_ptr所拥有。那么,在拷贝构造或赋值操作时,我们必须做特殊的处理来保证这个特性。auto_ptr的做法是”所有权转移“,即拷贝或赋值的源对象失去对”裸“指针的所有权,所以,与一般的拷贝构造函数,赋值函数不同,auto_ptr的拷贝构造函数,赋值函数的参数为引用而不是常引用。当然,一个auto_ptr也不能同时拥有两个以上的”裸“指针,所以拷贝或赋值的目标对象将现释放期原来所拥有的对象。

  这里的注意点是:

  1)因为一个auto_ptr被拷贝或赋值后,其已经失去对原对象的所有权,这个时候,对这个auto_ptr的解引用操作是不安全的。如下:

int* p = new int();
auto_ptr<int> ap1(p);
auto_ptr<int> ap2 = ap1;
cout<<*ap1; //错误,此时ap1只剩下一个NULL指针在手了

  这种情况较为隐藏的情形出现在将auto_ptr作为函数参数按值传递,因为在函数调用过程中在函数的作用域中会产生一个局部对象来接收传入的auto_ptr(拷贝构造),这样,传入的实参auto_ptr就失去了其对原对象的所有权,而原对象会在函数退出时被局部auto_ptr删除。如下:  

void f(auto_ptr<int> ap) {cout<<*ap}
auto_ptr<int> ap1(new int());
f(ap1);
cout<<*ap1; //错误,经过f(ap1)函数调用,ap1已经不再拥有任何对象了

  2)因为auto_ptr不具有值语义,所以auto_ptr不能被用在STL标准容器中。所谓值语义,是指符合以下条件的类型(假设有类A):

A a1;
A a2(a1);
A a3;
a3=a1;

  那么:a2 == a1, a3==a1

  很明显,auto_ptr不符合上述条件,STL标准容器要用到大量的拷贝赋值操作,并且假设其操作的类型符合以上条件。

  

shared_ptr

  auto_ptr由于它的破坏性复制语义,无法满足标准容器对元素的要求,因而不能放在标准容器中。boost库中提供了一种新型的智能指针shared_ptr,它解决了在多个指针间共享对象所有权的问题,同时也满足容器对元素的要求,因而可以安全地放入容器中。

  shared_ptr的作用同指针,但会记录有多少个shared_ptr共同指向同一个对象。这便是所谓的引用计数。一旦最后一个这个的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象就会被自动删除。这在非环形数据结构中防止资源泄漏很有帮助。

【C++】智能指针的更多相关文章

  1. enote笔记法使用范例(2)——指针(1)智能指针

    要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...

  2. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

  3. C++智能指针

    引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...

  4. EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针

    一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...

  5. 智能指针shared_ptr的用法

    为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...

  6. 智能指针unique_ptr的用法

    unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...

  7. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  8. C++ 引用计数技术及智能指针的简单实现

    一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...

  9. C++11智能指针读书笔记;

    智能指针是一个类对象,而非一个指针对象. 原始指针:通过new建立的*指针 智能指针:通过智能指针关键字(unique_ptr, shared_ptr ,weak_ptr)建立的指针 它的一种通用实现 ...

  10. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

随机推荐

  1. java Servlet中的过滤器Filter

    web.xml中元素执行的顺序listener->filter->struts拦截器->servlet. 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...

  2. 实验十五_安装新的int 9中断例程

    安装一个新的int 9中断例程,功能:在DOS下,按下“A”键后,除非不在松开,    如果松开,就显示满屏幕的“A”:其他的键照常处理. 提示:按下一个键时产生的扫描码称为通码,松开一个键产生的扫描 ...

  3. Lintcode: Rehashing

    The size of the hash table is not determinate at the very beginning. If the total size of keys is to ...

  4. Lintcode: O(1) Check Power of 2

    Using O(1) time to check whether an integer n is a power of 2. Example For n=4, return true For n=5, ...

  5. 位置式PID与增量式PID算法

    位置式PID与增量式PID算法  PID控制是一个二阶线性控制器     定义:通过调整比例.积分和微分三项参数,使得大多数的工业控制系统获得良好的闭环控制性能.     优点             ...

  6. oracle ebs request一直pending

    如果提交请求以后,状态一直是pending状态,可以在“工具”打开“Manager”,查看一下Maximum是否有设置错,另外pending的数量当前是多少. 如果Maximum是1,pending是 ...

  7. springmvc转发与重定向

    摘自http://elf8848.iteye.com/blog/875830 (1)我在后台一个controller跳转到另一个controller,为什么有这种需求呢,是这样的.我有一个列表页面,然 ...

  8. url传参

    1.两种url形式传参index.php/action/function/id/2   这种模式下:$_GET[action]就是function,$_GET[id]就是2

  9. VS中快速生成json数据格式对应的实体

    JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定的符号标注. {} 双 ...

  10. cvCreateImage函数说明(转载)

    cvCreateImage是openCV中的一个函数.OpenCV是Intel公司支持的开源计算机视觉库. cvCreateImage:创建首地址并分配存储空间    IplImage* cvCrea ...