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____
本文通过示例代码详细解析了C++中异常处理机制下对象拷贝的行为特征,包括不同情况下异常对象如何被传递及析构的过程。揭示了即使是引用参数也会创建对象临时拷贝的现象,并展示了不同捕获类型(引用、值、指针)的影响。
932

被折叠的 条评论
为什么被折叠?



