這篇討論有效的揭露了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的拷貝構造函數,不是我所想象的是基類也是調用拷貝構造函數。