http://blog.csdn.net/g5dsk/article/details/5851614
引发异常时, 编译器总是创建一个临时拷贝, 即使异常规范和 catch 块中指定的是引用.
备注: 指定引用的目的并不是避免创建拷贝以提高效率, 而是基类引用可以执行派生类对象.
- // Code
- #include <iostream>
- class MyException
- {
- public:
- MyException()
- {
- ++nCnt;
- nObjId = nCnt;
- std::cout << "<+" << nObjId << "> MyException default constructor has been invoked. " << std::endl;
- }
- MyException(const MyException& /* rhs */) // Comment 'rhs' to avoid warning C4100.
- {
- ++nCnt;
- nObjId = nCnt;
- std::cout << "<+" << nObjId << "> MyException copy constructor has been invoked. " << std::endl;
- }
- virtual ~MyException()
- {
- std::cout << "<-" << nObjId << "> MyException destructor has been invoked. " << std::endl;
- --nCnt;
- nObjId = -100000; // Set object id invalid.
- }
- int ObjId()
- {
- return nObjId;
- }
- private:
- static int nCnt;
- int nObjId;
- };
- /* static */ int MyException::nCnt = 0; // Cannot use 'static' here!
- int main()
- {
- try
- {
- MyException me;
- throw me;
- }
- catch (MyException& me)
- {
- std::cout << "<" << me.ObjId() << "> The exception has been caught. " << std::endl;
- std::cout << "____A____" << std::endl;
- }
- std::cout << "____B____" << std::endl;
- std::cout << std::endl;
- try
- {
- MyException me;
- throw me;
- }
- catch (MyException me)
- {
- std::cout << "<" << me.ObjId() << "> The exception has been caught. " << std::endl;
- std::cout << "____A____" << std::endl;
- }
- std::cout << "____B____" << std::endl;
- std::cout << std::endl;
- try
- {
- MyException me;
- std::cout << "In try-block, address of me is 0x" << &me << std::endl;
- throw &me;
- }
- catch (MyException* pme)
- {
- std::cout << "In catch-block, pme points to 0x" << pme << std::endl;
- std::cout << "<" << pme->ObjId() << "> The exception has been caught. " << std::endl;
- std::cout << "____A____" << std::endl;
- }
- std::cout << "____B____" << std::endl;
- std::cout << std::endl;
- try
- {
- MyException* pme = new MyException;
- std::cout << "In try-block, pme points to 0x" << pme << std::endl;
- throw pme;
- }
- catch (MyException* pme)
- {
- std::cout << "In catch-block, pme points to 0x" << pme << std::endl;
- std::cout << "<" << pme->ObjId() << "> The exception has been caught. " << std::endl;
- std::cout << "____A____" << std::endl;
- }
- std::cout << "____B____" << std::endl;
- std::cout << std::endl;
- try
- {
- MyException* pme = new MyException;
- std::cout << "In try-block, pme points to 0x" << pme << std::endl;
- throw pme;
- }
- catch (MyException* pme)
- {
- std::cout << "In catch-block, pme points to 0x" << pme << std::endl;
- std::cout << "<" << pme->ObjId() << "> The exception has been caught. " << std::endl;
- delete pme;
- pme = NULL;
- std::cout << "____A____" << std::endl;
- }
- std::cout << "____B____" << std::endl;
- return 0;
- }
- // Output
- <+1> MyException default constructor has been invoked.
- <+2> MyException copy constructor has been invoked.
- <-1> MyException destructor has been invoked.
- <2> The exception has been caught.
- ____A____
- <-2> MyException destructor has been invoked.
- ____B____
- <+1> MyException default constructor has been invoked.
- <+2> MyException copy constructor has been invoked.
- <+3> MyException copy constructor has been invoked.
- <-1> MyException destructor has been invoked.
- <3> The exception has been caught.
- ____A____
- <-3> MyException destructor has been invoked.
- <-2> MyException destructor has been invoked.
- ____B____
- <+1> MyException default constructor has been invoked.
- In try-block, address of me is 0x0038FBA0
- <-1> MyException destructor has been invoked.
- In catch-block, pme points to 0x0038FBA0
- <-100000> The exception has been caught.
- ____A____
- ____B____
- <+1> MyException default constructor has been invoked.
- In try-block, pme points to 0x003A1EA0
- In catch-block, pme points to 0x003A1EA0
- <1> The exception has been caught.
- ____A____
- ____B____
- <+2> MyException default constructor has been invoked.
- In try-block, pme points to 0x003A1ED8
- In catch-block, pme points to 0x003A1ED8
- <2> The exception has been caught.
- <-2> MyException destructor has been invoked.
- ____A____
- ____B____