调用一个函数的时候,控制器最终会回到调用端,而抛出异常的时候,控制器不会回到抛出端。在抛出异常的时候到底发生了什么呢?
1调用拷贝构造函数,复制将要抛出的信息,意味着发生异常的时候总是会发生复制的行为(对抛出信息的复制);
2调用析构函数,析构抛出端的无用资源;
3 throw后面的代码不会执行;
4 throw 对象通过by-value 的时候会发生2次调用拷贝构造函数, by-reference的时候只发生一次调用拷贝构造函数。
5在catch匹配中,针对于base-class和derived-class设计的catch语句,采取的是最先匹配原则(虚函数采取的是最佳匹配原则)。故在catch的顺序上不要吧基类放在派生类之前。
ps:在返回时,不要返回一个指向局部对象的指针,返回一个指向已被销毁的对象是无意义的,传参最好用by-point or by-reference方式,而返回是通过by-value方式。而在try-catch中的throw中,这里都会发生复制行为的,故catch最好是通过 by-reference方式;
测试代码
#include <iostream>
using namespace std;
class Widget
{
public:
Widget();
Widget(Widget& w);
~Widget();
private:
};
class Book
{
public:
Book();
Book(Book& k);
~Book();
private:
};
Book::Book(Book& k)
{
cout << "Book-copy-construct is called" << endl;
}
Book::Book()
{
cout << "Book construct" << endl;
}
Book::~Book()
{
cout << "Book deconstruct" << endl;
}
Widget::Widget()
{
cout << "I am called;" << endl;
}
Widget::Widget(Widget& w)
{
cout << "copy-constuct is called" << endl;
}
Widget::~Widget()
{
cout << "I am deconstruct"<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
try{
Widget w;
Book b;
cout << "分割1" << endl;
Widget& k = w;
/*throw w;*/
throw k;
cout << "分割1" << endl;
}
//catch (Widget w)
//{
//}
catch (Widget& k)
{
}
system("pause");
return 0;
}