【问题标题】:Throwing an exception in a constructor of a c++ class在 C++ 类的构造函数中抛出异常
【发布时间】:2017-02-09 13:02:52
【问题描述】:

下面的代码是否表示内存泄漏?

Test 类的析构函数没有被调用(屏幕上没有输出),我假设分配给 Int 类数组的所有内存都没有返回给系统?我的假设正确吗?如果发生异常,我应该如何收回在构造函数中分配的资源?

#include <iostream>
using namespace std;

class Int{
   public:
      int v;
      Int(){
        cout<<"inside Int constructor ..."<<endl;
      }

      ~Int(){
        cout<<"inside Int destructor ..."<<endl;
      }
};

class Test{
    public:
    Int* a;

    Test(){
        a=new Int[10];
        cout<<"inside Test constructor ..."<<endl;
        throw(0);
    }

    ~Test(){
      delete [] a;
      cout<<"inside Test destructor ..."<<endl;
    }
};

int main(){
   try{
      Test T;
   }
   catch (int e){
        cout<<"Error!!!"<<endl;
   }

    return 0;
}      

【问题讨论】:

    标签: c++ memory-leaks constructor exception-handling destructor


    【解决方案1】:

    没有调用析构函数,因为对象从未完全构造。在部分构造的对象上调用它可能更危险,因为它会尝试撤消从未完成的事情。作为程序员,您有责任确保在发生异常时不会从构造函数中泄漏内存(或任何其他资源)。

    但是,基类和成员变量的析构函数会被调用!这就是为什么在大多数情况下最好依赖智能指针或容器,它们将为您处理资源管理。尝试像这样改变你的班级:

    #include <memory>
    
    class Test{
        public:
        std::unique_ptr<Int[]> a;
    
        Test(){
            a=std::make_unique<Int[]>(10);
            cout<<"inside Test constructor ..."<<endl;
            throw(0);
        }
    
        ~Test(){
          //no need to delete[] a;
          cout<<"inside Test destructor ..."<<endl;
        }
    };
    

    这是一个双赢的局面。你会看到Int的析构函数会被调用,你不需要手动处理内存。

    【讨论】:

      【解决方案2】:

      我想出了一个解决方案,但不确定这是一个好的设计还是正确的方法。你能评论一下吗?

      #include <iostream>
      using namespace std;
      
      class Int{
          public:
          int v;
          Int(){
              cout<<"inside Int constructor ..."<<endl;
          }
      
            ~Int(){
              cout<<"inside Int destructor ..."<<endl;
          }
      };
      
      class Test{
          public:
          Int* a;
      
          Test(){
              try{
                  a=new Int[10];
                  cout<<"inside Test constructor ..."<<endl;
                  throw(0); // exception is thrown
                 }
      
               catch (int e){
                     delete [] a;
                     cout<<"Error!!!"<<endl;
                 }
              }
      
          ~Test(){
            delete [] a;
            cout<<"inside Test destructor ..."<<endl;
          }
      };
      
      int main(){
      
            Test T;
      
      
            return 0;
      }      
      

      【讨论】:

        猜你喜欢
        • 2014-11-03
        • 2019-03-11
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 2018-05-21
        • 2011-11-04
        • 1970-01-01
        相关资源
        最近更新 更多