cout <<"Exception caught in testException()"<< endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
testException(NULL);
system("pause");
return 0;
}
第10行定义一个类MyError,里面存储一个记录异常信息的字符串,第35行抛出MyError类型的异常,第38行捕获MyError类型的异常,如果捕获成功则打印异常信息what();如果抛出的异常不是MyError类型,则第42行的catch (...)形式的代码将发挥作用,"..."代表即将捕获的异常类型是任意类型的。win32上运行程序,打印输出如下所示 MyError() called ~MyError() called NULL input in testException ~MyError() called 如果抛出异常而没被捕获会发生什么呢?让我们做个实验,把testException函数改一下,在第一个catch里面加上一行代码throw,这种后面紧跟分号,并且出现在catch中的throw表明程序在重新抛出异常,这个异常将无法被本身的try...catch所捕获。
点击(此处)折叠或打开
void testException(char* input)
{
try
{
if(!input)
{
throw MyError("NULL input in testException");
}
}
catch (MyError& aError)
{
cout << aError.what()<< endl;
throw;
}
catch (...)
{
cout <<"Exception caught in testException()"<< endl;
cout <<"Exception caught in testException()"<< endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
testException(NULL);
system("pause");
return 0;
}
第40行new一个Name的对象,aName指向这个对象,第44行抛出异常,然后程序直接跳转到第49行,以下是程序的输出, CTOR of Name() called Michael
我们看到,Name类本身的析构函数没有被调用,而这也就意味着内存发生了泄露!这是C/C++程序员最不愿因看到的。尤其在大型的项目上,追查一个内存泄露bug经常要耗费数日。好吧,那我们看看如何避免这类问题的发生呢?最简单的办法是把testException函数做一个小小的改动,在抛出异常之前delete aName,
点击(此处)折叠或打开
void testException(char* input)
{
try
{
char myName[]="Michael";
Name *aName = new Name(myName, sizeof(myName));
aName->print();
if(!input)
{
delete aName;
throw runtime_error("NULL input");
}
}
catch (...)
{
cout <<"Exception caught in testException()"<< endl;
}
}
这样程序的输出就变为 CTOR of Name() called Michael DTOR of Name() called
这样就避免了内存泄露。