引发异常时, 编译器总是创建一个临时拷贝...

http://blog.csdn.net/g5dsk/article/details/5851614


引发异常时, 编译器总是创建一个临时拷贝, 即使异常规范和 catch 块中指定的是引用.

备注: 指定引用的目的并不是避免创建拷贝以提高效率, 而是基类引用可以执行派生类对象.

  1. // Code   
  2.    
  3. #include <iostream>      
  4.       
  5.       
  6. class MyException      
  7. {     
  8. public:      
  9.     MyException()      
  10.     {     
  11.         ++nCnt;      
  12.         nObjId = nCnt;   
  13.         std::cout << "<+" << nObjId << "> MyException default constructor has been invoked. " << std::endl;      
  14.     }      
  15.       
  16.     MyException(const MyException& /* rhs */// Comment 'rhs' to avoid warning C4100.      
  17.     {     
  18.         ++nCnt;      
  19.         nObjId = nCnt;   
  20.         std::cout << "<+" << nObjId << "> MyException copy constructor has been invoked. " << std::endl;      
  21.     }     
  22.       
  23.     virtual ~MyException()     
  24.     {     
  25.         std::cout << "<-" << nObjId << "> MyException destructor has been invoked. " << std::endl;      
  26.         --nCnt;   
  27.         nObjId = -100000; // Set object id invalid.   
  28.     }      
  29.       
  30.     int ObjId()     
  31.     {     
  32.         return nObjId;      
  33.     }     
  34. private:      
  35.     static int nCnt;      
  36.     int nObjId;   
  37. };      
  38.       
  39. /* static */ int MyException::nCnt = 0; // Cannot use 'static' here!      
  40.       
  41.       
  42. int main()     
  43. {     
  44.     try      
  45.     {     
  46.         MyException me;      
  47.         throw me;      
  48.     }      
  49.     catch (MyException& me)      
  50.     {     
  51.         std::cout << "<" << me.ObjId() << "> The exception has been caught. " << std::endl;      
  52.         std::cout << "____A____" << std::endl;      
  53.     }      
  54.       
  55.     std::cout << "____B____" << std::endl;      
  56.       
  57.     std::cout << std::endl;   
  58.       
  59.     try  
  60.     {  
  61.         MyException me;      
  62.         throw me;      
  63.     }  
  64.     catch (MyException me)   
  65.     {     
  66.         std::cout << "<" << me.ObjId() << "> The exception has been caught. " << std::endl;      
  67.         std::cout << "____A____" << std::endl;      
  68.     }      
  69.       
  70.     std::cout << "____B____" << std::endl;      
  71.       
  72.     std::cout << std::endl;   
  73.       
  74.     try  
  75.     {  
  76.         MyException me;      
  77.         std::cout << "In try-block, address of me is 0x" << &me << std::endl;   
  78.         throw &me;      
  79.     }  
  80.     catch (MyException* pme)   
  81.     {     
  82.         std::cout << "In catch-block, pme points to 0x" << pme << std::endl;   
  83.         std::cout << "<" << pme->ObjId() << "> The exception has been caught. " << std::endl;      
  84.         std::cout << "____A____" << std::endl;      
  85.     }      
  86.       
  87.     std::cout << "____B____" << std::endl;      
  88.       
  89.     std::cout << std::endl;   
  90.       
  91.     try  
  92.     {  
  93.         MyException* pme = new MyException;      
  94.         std::cout << "In try-block, pme points to 0x" << pme << std::endl;   
  95.         throw pme;   
  96.     }  
  97.     catch (MyException* pme)   
  98.     {     
  99.         std::cout << "In catch-block, pme points to 0x" << pme << std::endl;   
  100.         std::cout << "<" << pme->ObjId() << "> The exception has been caught. " << std::endl;      
  101.         std::cout << "____A____" << std::endl;      
  102.     }      
  103.       
  104.     std::cout << "____B____" << std::endl;   
  105.       
  106.     std::cout << std::endl;   
  107.       
  108.     try  
  109.     {  
  110.         MyException* pme = new MyException;      
  111.         std::cout << "In try-block, pme points to 0x" << pme << std::endl;   
  112.         throw pme;   
  113.     }  
  114.     catch (MyException* pme)   
  115.     {     
  116.         std::cout << "In catch-block, pme points to 0x" << pme << std::endl;   
  117.         std::cout << "<" << pme->ObjId() << "> The exception has been caught. " << std::endl;      
  118.         delete pme;   
  119.         pme = NULL;   
  120.         std::cout << "____A____" << std::endl;      
  121.     }      
  122.       
  123.     std::cout << "____B____" << std::endl;      
  124.       
  125.     return 0;      
  126. }      

  1. // Output   
  2.    
  3. <+1> MyException default constructor has been invoked.  
  4. <+2> MyException copy constructor has been invoked.  
  5. <-1> MyException destructor has been invoked.  
  6. <2> The exception has been caught.  
  7. ____A____  
  8. <-2> MyException destructor has been invoked.  
  9. ____B____  
  10.   
  11. <+1> MyException default constructor has been invoked.  
  12. <+2> MyException copy constructor has been invoked.  
  13. <+3> MyException copy constructor has been invoked.  
  14. <-1> MyException destructor has been invoked.  
  15. <3> The exception has been caught.  
  16. ____A____  
  17. <-3> MyException destructor has been invoked.  
  18. <-2> MyException destructor has been invoked.  
  19. ____B____  
  20.   
  21. <+1> MyException default constructor has been invoked.  
  22. In try-block, address of me is 0x0038FBA0  
  23. <-1> MyException destructor has been invoked.  
  24. In catch-block, pme points to 0x0038FBA0  
  25. <-100000> The exception has been caught.  
  26. ____A____  
  27. ____B____  
  28.   
  29. <+1> MyException default constructor has been invoked.  
  30. In try-block, pme points to 0x003A1EA0  
  31. In catch-block, pme points to 0x003A1EA0  
  32. <1> The exception has been caught.  
  33. ____A____  
  34. ____B____  
  35.   
  36. <+2> MyException default constructor has been invoked.  
  37. In try-block, pme points to 0x003A1ED8  
  38. In catch-block, pme points to 0x003A1ED8  
  39. <2> The exception has been caught.  
  40. <-2> MyException destructor has been invoked.  
  41. ____A____  
  42. ____B____  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值