在 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;
}
下面的代码是否表示内存泄漏?
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;
}