zoukankan      html  css  js  c++  java
  • auto_ptr浅析

    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  <<  " "; }
        ~A() { cout << "destroy A" << id << " "; }
    private:
        static int count;
        int id;
    };
     
    int A::count = 0;
     
    /*调用该函数会丢失掉所有权*/
    void sink(auto_ptr<A> a)
    {
        cout << "Enter sink() ";
    }
     
    /*调用该函数会创建对象,并获取所有权*/
    auto_ptr<A> create()
    {
        cout << "Enter create() ";
        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() ";
        sink(a2);/*丢失所有权,会发现a2的释放在sink函数中进行*/
        cout << "Exit sink() ";
        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元素之间就不等价了。

  • 相关阅读:
    史上最走心的Webpack4.0中级教程——配置之外你应该知道事
    javascript基础修炼(11)——DOM-DIFF的实现
    一统江湖的大前端(7)React.js-从开发者到工程师
    express中间件系统的基本实现
    js中如何在不影响既有事件监听的前提下新增监听器
    Zabbix的应用(6)----常见错误
    Ansible初级应用
    一个好用的小工具 thefuck
    使用python读取word文件里的表格信息
    01010_Eclipse中项目的jar包导入与导出
  • 原文地址:https://www.cnblogs.com/yzl050819/p/5912438.html
Copyright © 2011-2022 走看看