这篇讨论有效的揭露了try, throw , catch 的本质的工作方法。
源代码如下:
#include <iostream>
using namespace std;
class Mammal
{
public:
Mammal()
{
cout << "Constructing Mammal @ " << this << endl;
}
Mammal(const Mammal& source)
{
cout << "Copy Constructing Mammal @ " << this << " from " <<
&source << endl;
}
~Mammal()
{
cout << "Destructing Mammal @ " << this << endl;
}
virtual const char* MyType() const
{
return "Mammal";
}
};
class Cat : public Mammal
{
public:
Cat()
{
cout << "Constructing Cat @ " << this << endl;
}
Cat(const Cat& source)
{
cout << "Copy Constructing Cat @ " << this << " from " <<
&source << endl;
}
~Cat()
{
cout << "Destructing Cat @ " << this << endl;
}
virtual const char* MyType() const
{
return "Cat";
}
};
int main(int argc, char *argv[])
{
try
{
Cat fluffy;
Mammal& fluffyRef = fluffy;
throw fluffyRef;
}
catch (const Mammal &m)
{
cout << "Caught a " << m.MyType() << endl;
return 0;
}
cout << "Nothing Caught" << endl;
return 0;
}
输出:
Constructing Mammal @ 0012FF50
Constructing Cat @ 0012FF50
Copy Constructing Mammal @ 0012FE60 from 0012FF50
Destructing Cat @ 0012FF50
Destructing Mammal @ 0012FF50
Caught a Mammal
Destructing Mammal @ 0012FE60
对这个例子我的感悟:
- throw 的用法, 它将抛出某个具体的object(异常类),这个类将被catch所捕捉。由于fluffRef是一个Mammal的reference,但是它的instance 其实是一个cat。但是在throw抛出的时候,throw其实跟不管instance 的type,它只是根据抛出对象申明的type 拷贝构造出一个新的临时的对象以作为异常对象。所以,Throw 抛出的时候,不看对象instance的type,而是看这个当前申明的类型。
- 如果我们将代码改成
try
{
Cat fluffy;
Cat& fluffyRef = fluffy;
throw fluffyRef;
}
这个时候,当然throw 的是cat。 注意,这个地方throw调用 Mammal和默认构造函数和Cat的拷贝构造函数,不是我所想象的是基类也是调用拷贝构造函数。