在 C++ 的构造函数中抛出异常 class

Throwing an exception in a constructor of a c++ class

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

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

#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;
}      

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

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

#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的析构函数会被调用,你不需要手动处理内存

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

#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;
}