zoukankan      html  css  js  c++  java
  • 智能指针之auto_ptr

    auto_ptr是C++标准库里的所谓智能指针之一。是用来防止内存泄漏的一种方式。
    它不允许多个指针指向同一块内存,而且能在方法返回时自动释放所指的内存。这样即使在程序因为异常退出时也能释放掉所占用的资源,不用造成内存泄漏。
    void f()
    {
        classA* ptr = new classA;
        try{
        ...
        }
        catch(...){
       delete ptr;
       throw;
        }
    delete ptr;
    }
    这样也可以达到没有内存泄漏的目的,但是代码量比较大,很麻烦。
    #include <memory>
    void f()
    {
       std::auto_ptr<classA> ptr(new classA);
       ...
    }
    这样比较方便,不需要再delete,甚至不用catch,内存也不会泄漏。
     
    auto_ptr和普通的指针的用法一样,*是取值,->用来访问成员,但是它没有提供指针的数值运算,比如++。而且也不允许通过将普通对象的指针赋值给它来初始化。如:
    std::auto_ptr<classA> ptr1<new classA>;  //OK
    std::auto_ptr<classA> ptr2= new calssA;  //ERROR
    第二个就是非法的,因为auto_ptr不能指向普通指针,只能指向auto_ptr类型。
     
    auto_ptr指针所指的数据,只能有一个指针指向,当指针发生赋值时,其实原指针就为NULL,即它不指向任何对象了。
    std::auto_ptr<classA> ptr1<new classA>; 
    std::auto_ptr<classA> ptr2<new classA>;
    ptr2=ptr1; //ptr2所指的对象被delete(自动回收),ptr2指向ptr1原来所指的对象,而ptr1为NULL。
    这一性质也导致,一般不将auto_ptr指针作为参数传递给方法,因为进入方法时要复制指针,这就相当于原指针不指向任何东西,而如果方法在最后不将指针返回的话,原对象因为无人指向,因此在方法结束时被删除。因此,如果不是想传递参数,请不要把auto_ptr作为参数或者返回值。
    将auto_ptr的引用作为参数传递会使指针的拥有权混乱,因为引用不改变指针的所有权,尽量还是别传引用。
    如果不想改变auto_ptr的拥有权,可以把它定义成const,如:
    std::auto_ptr<int>f()
    {
    const std::auto_ptr<int>p(new int);
    std::auto_ptr<int>q (new int);
    *p =42; //OK 赋值伟42,允许
    bad_print(p);  //compile time error ,不能作为参数传递,这样拥有权就变了
    *p=*q; //OK ,改变值为0,允许
    p=q;   //compile time error ,p不能指向别的地方了
    return p;  //compile time error,这一返回,拥有权就变了,不允许
    }

    析构函数只有在构造函数调用成功之后才会被调用,因为如果构造函数运行半途出现异常退出了,不会调用析构函数,很可能造成内存泄漏。如:

    class ClassB

    {

       private:

        ClassA* ptr1;

        ClassA* ptr2;

       public:

      ClassB (ClassA val1,ClassA val2):ptr1(new ClassA(val1),new ClassA(val2)){}  //如果ptr2(new ClassA(val2))出现异常而退出,就不会调用析构  函 数,因此就会泄漏ptr1所指的对象。

    ...

     ~ClassB()

    {

       delete ptr1;

       delete ptr2;

    }

    };

    小结一下吧:

    1.auto_ptr对象不能共享同一个指针拥有权。

    2.不能用于数组,因为它的析构函数不能调用delete[].

    3.它不是万能的智能指针,比如它不能用来计数,而share_ptr是干这个的,它允许共享拥有权,会在引用计数为0时自动删除对象。

    4.auto_ptr不能作为容器中的element使用。

  • 相关阅读:
    图的深度遍历
    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历

    满汉全席
    2-sat(模板)
    2-sat
    花匠
    维护序列NOI2005
    序列终结者
    杨辉三角
  • 原文地址:https://www.cnblogs.com/encode/p/3682686.html
Copyright © 2011-2022 走看看