auto_ptr是C++标准库中(<utility>)为了解决资源泄漏的问题提供的一个智能指针类模板(注意:这只是一种简单的智能指针)

auto_ptr的实现原理其实就是RAII,在构造的时候获取资源,在析构的时候释放资源,并进行相关指针操作的重载,使用起来就像普通的指针。

std::auto_ptr<ClassA> pa(new ClassA);

下面主要分析一下auto_ptr的几个要注意的地方:

1,Transfer of Ownership

auto_ptr与boost库中的share_ptr不同的,auto_ptr没有考虑引用计数,因此一个对象只能由一个auto_ptr所拥有,在给其他auto_ptr赋值的时候,会转移这种拥有关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <utility>
#include <iostream>
using namespace std;
 
class A
{
public:
    A() { id = ++count; cout << "create A" << id  <<  "\n"; }
    ~A() { cout << "destroy A" << id << "\n"; }
private:
    static int count;
    int id;
};
 
int A::count = 0;
 
/*调用该函数会丢失掉所有权*/
void sink(auto_ptr<A> a)
{
    cout << "Enter sink()\n";
}
 
/*调用该函数会创建对象,并获取所有权*/
auto_ptr<A> create()
{
    cout << "Enter create()\n";
    auto_ptr<A> a(new A());
    return a;
}
 
int main(int argc, char *argv[])
{
    auto_ptr<A> a1 = create();
    auto_ptr<A> a2 = a1; /*转移所有权,此时a1无效了*/
    auto_ptr<A> a3(new A());
    cout << "Exit create()\n";
    sink(a2);/*丢失所有权,会发现a2的释放在sink函数中进行*/
    cout << "Exit sink()\n";
    return 0;
}
 
输出结果是:<br>Enter create()<br>create A1<br>create A2<br>Exit create()<br>Enter sink()<br>destroy A1<br>Exit sink()<br>destroy A2<br><br>

2,从上可知由于在赋值,参数传递的时候会转移所有权,因此不要轻易进行此类操作。

比如:std::auto_ptr<ClassA> pa(new ClassA());

bad_print(pa); //丢失了所有权

pa->...; //Error

3,使用auto_ptr作为成员变量,以避免资源泄漏。

为了防止资源泄漏,我们通常在构造函数中申请,析构函数中释放,但是只有构造函数调用成功,析构函数才会被调用,换句话说,如果在构造函数中产生了异常,那么析构函数将不会调用,这样就会造成资源泄漏的隐患。

比如,如果该类有2个成员变量,指向两个资源,在构造函数中申请资源A成功,但申请资源B失败,则构造函数失败,那么析构函数不会被调用,那么资源A则泄漏。

为了解决这个问题,我们可以利用auto_ptr取代普通指针作为成员变量,这样首先调用成功的成员变量的构造函数肯定会调用其析构函数,那么就可以避免资源泄漏问题。

4,不要误用auto_ptr

1)auto_ptr不能共享所有权,即不要让两个auto_ptr指向同一个对象。

2)auto_ptr不能指向数组,因为auto_ptr在析构的时候只是调用delete,而数组应该要调用delete[]。

3)auto_ptr只是一种简单的智能指针,如有特殊需求,需要使用其他智能指针,比如share_ptr。

4)auto_ptr不能作为容器对象,STL容器中的元素经常要支持拷贝,赋值等操作,在这过程中auto_ptr会传递所有权,那么source与sink元素之间就不等价了。

auto_ptr浅析的更多相关文章

  1. auto_ptr浅析(转载)

    转载自http://www.cnblogs.com/qytan36/archive/2010/06/28/1766555.html auto_ptr是C++标准库中(<utility>)为 ...

  2. auto_ptr 浅析(转)

    auto_ptr是C++标准库中(<utility>)为了解决资源泄漏的问题提供的一个智能指针类模板(注意:这只是一种简单的智能指针) auto_ptr的实现原理其实就是RAII,在构造的 ...

  3. C++ 智能指针浅析

    C++ 智能指针浅析 为了解决 C++ 中内存管理这个老大难问题,C++ 11 中提供了三种可用的智能指针.(早期标准库中还存在一种 auto_ptr,但由于设计上的缺陷,已经被 unique_ptr ...

  4. SQL Server on Linux 理由浅析

    SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...

  5. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  6. 高性能IO模型浅析

    高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking  ...

  7. netty5 HTTP协议栈浅析与实践

      一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...

  8. Jvm 内存浅析 及 GC个人学习总结

    从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...

  9. 从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler

    熟悉WebForm开发的朋友一定都知道,Page类必须实现一个接口,就是IHttpHandler.HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...

随机推荐

  1. 《JS权威指南学习总结--8.8 函数式编程和8.8.1使用函数处理数组》

    内容要点:    和Lisp.Haskell不同,JS并非函数式编程语言,但在JS中可以像操控对象一样操控函数,   也就是说可以在JS中应用函数式编程技术.ES5中的数组方法(诸如map()和red ...

  2. apache动态编译与静态编译

    静态: 在使用./configure 编译的时候,如果不指定某个模块为动态,即没有使用:enable-mods-shared=module或者enable-module=shared 这个2个中的一个 ...

  3. 3、Hibernate三态间的转换

    学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...

  4. openwrt启动过程(脚本)

    来源:  http://wiki.openwrt.org/doc/techref/preinit_mount#first.boot 基本的openwrt启动顺序为: 1.boot loader loa ...

  5. Ambari安装组件出错

    Caught an exception while executing custom service command: <class 'ambari_agent.AgentException.A ...

  6. JS 之设置元素样式的改变,可以利用样式框架

    如果已经将某个元素的样式设定好了,又想改变,可以利用样式框架: function setStyle(obj,attr,value){ obj.style[attr]=value;//注意此处attr的 ...

  7. Python 学习笔记6

    做人要有目标感! 继续学习Python哦.

  8. unity 退到桌面的 OnApplicationPause

    void OnApplicationFocus( bool isFocus ) { // Debug.Log("--------OnApplicationPause---" + i ...

  9. MFC下对文件及文件夹的操作(复制、剪切、删除、创建文件夹,写文件)

    一.文件夹的创建 void CFileOperationDlg::OnButtonMakeFolder() { // TODO: Add your control notification handl ...

  10. Memcached启动脚本

    ched: MemCached Daemon # # chkconfig: - # description: MemCached Daemon # # Source function library. ...