16.3.3 构造函数中抛出异常
对局部类对象来说,如果其构造函数没有完全执行,便由throw语句退出,其析构函数不会被执行,这可能会造成一定程度的内存泄露和资源浪费,如代码16.12所示。
代码16.12 构造函数中抛出异常ThrowByAConstructor
<——————————-文件名:example1612.cpp————————————————> 01 #include<iostream> 02 using namespace std; 03 class OnlyOne 04 { 05 static bool isOne;//静态成员isOne 06 int num; 07 public: 08 OnlyOne(int n) 09 { 10 num=n; 11 cout<<num<<",进入构造函数"<<endl; 12 if(isOne)//如果已经定义了一个示例,抛出异常 13 throw"已经有一个实例了"; 14 isOne=true; 15 cout<<num<<",构造函数执行完毕"<<endl; 16 } 17 ~OnlyOne() 18 { 19 cout<<num<<",析构函数被执行"<<endl; 20 } 21 }; 22 bool OnlyOne:isOne=false;//初始化为false 23 int main() 24 { 25 try 26 { 27 OnlyOne x(5); 28 OnlyOne y(6); 29 } 30 catch(const char*s) 31 { 32 cout<<s<<endl; 33 } 34 return 0; 35 }
输出结果如下所示。
5,进入构造函数 5,构造函数执行完毕 6,进入构造函数 5,析构函数被执行 已经有一个实例了
【代码解析】代码第5行OnlyOne类中定义了一个静态成员isOne,初始化为false,如果创建了一个对象后,在代码第14行将其更改为true,在下次再创建对象时,构造函数便会抛出异常“已经有一个实例了”。从输出结果可以看出,在执行catch块之前,类对象x的析构函数被执行,而y由于构造函数执行不完全,其析构函数得不到执行。