fork download
  1. #include <iostream>
  2.  
  3. struct A
  4. {
  5. A( int i ) : v(i)
  6. {
  7. if( v > 102 ) { std::cout << "\n*** throw ***\n\n" ; throw 100 ; }
  8. std::cout << "A::constructor v == " << v << " -- " ;
  9. }
  10. ~A() { std::cout << "A::destructor v == " << v << '\n' ; }
  11.  
  12. const int v ;
  13. };
  14.  
  15. struct B
  16. {
  17. B( int i ) : a(i) { std::cout << "B::constructor: object at " << this << '\n' ; }
  18. ~B() { std::cout << "B::destructor: object at " << this << " -- " ; }
  19.  
  20. A a ;
  21. };
  22.  
  23. struct C
  24. {
  25. C( int i ) : one(i), many { i+1, i+2, i+3, i+4 }
  26. { std::cout << "C::constructor\n" ; }
  27.  
  28. ~C() { std::cout << "C::destructor\n" ; }
  29.  
  30. B one ;
  31. B many[4] ;
  32.  
  33. static void* operator new( std::size_t sz )
  34. { std::cout << "\n+++ C::operator new\n\n" ; return ::new char[sz] ; }
  35.  
  36. static void operator delete( void* p )
  37. {
  38. std::cout << "\n+++ C::operator delete\n\n" ;
  39. return ::delete static_cast<char*>(p) ;
  40. }
  41.  
  42. // ... new[], delete[]
  43. };
  44.  
  45. int main()
  46. {
  47. // no exceptions are thrown
  48. try { C c1(0) ; std::cout << "ok\n" ; }
  49. catch( int ) { std::cout << "constructor of c1 threw\n" ; }
  50. // objects constructed are destroyed in reverse order
  51.  
  52. std::cout << "\n-------------------------------------\n" ;
  53.  
  54. // constructor of C : first construct members (5 object of type B)
  55. // each constructor of B : first construct members (an object of type A)
  56. // constructor of A
  57. // after three objects of type B are created, C::one, C::many[0], C::many[1]
  58. // the constructor of the fourth B C::many[2] =>
  59. // constructor of A with i == 103 => which throws
  60. // the objects which had been constructed are destroyed in reverse order
  61. // of construction: C::many[1], C::many[0], C::one
  62. // (each of which destroys the contained sub-object of type A)
  63. try { C c2(100) ; std::cout << "ok\n" ; }
  64. catch( int ) { std::cout << "\n*** constructor of c2 threw ***\n" ; }
  65.  
  66. std::cout << "\n-------------------------------------\n" ;
  67.  
  68. // same as above, the storage duration does not make a difference
  69. // except that memory that was allocated by C::operator new
  70. // would be released by C::operator delete
  71.  
  72. try { C* p = new C(100) ; std::cout << "ok\n" ; delete p ; }
  73. catch( int ) { std::cout << "\n*** constructor of C threw ***\n" ; }
  74. }
  75.  
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
A::constructor v == 0 -- B::constructor: object at 0xbfb6a66c
A::constructor v == 1 -- B::constructor: object at 0xbfb6a670
A::constructor v == 2 -- B::constructor: object at 0xbfb6a674
A::constructor v == 3 -- B::constructor: object at 0xbfb6a678
A::constructor v == 4 -- B::constructor: object at 0xbfb6a67c
C::constructor
ok
C::destructor
B::destructor: object at 0xbfb6a67c -- A::destructor v == 4
B::destructor: object at 0xbfb6a678 -- A::destructor v == 3
B::destructor: object at 0xbfb6a674 -- A::destructor v == 2
B::destructor: object at 0xbfb6a670 -- A::destructor v == 1
B::destructor: object at 0xbfb6a66c -- A::destructor v == 0

-------------------------------------
A::constructor v == 100 -- B::constructor: object at 0xbfb6a66c
A::constructor v == 101 -- B::constructor: object at 0xbfb6a670
A::constructor v == 102 -- B::constructor: object at 0xbfb6a674

*** throw ***

B::destructor: object at 0xbfb6a674 -- A::destructor v == 102
B::destructor: object at 0xbfb6a670 -- A::destructor v == 101
B::destructor: object at 0xbfb6a66c -- A::destructor v == 100

*** constructor of c2 threw ***

-------------------------------------

+++ C::operator new

A::constructor v == 100 -- B::constructor: object at 0x9513008
A::constructor v == 101 -- B::constructor: object at 0x951300c
A::constructor v == 102 -- B::constructor: object at 0x9513010

*** throw ***

B::destructor: object at 0x9513010 -- A::destructor v == 102
B::destructor: object at 0x951300c -- A::destructor v == 101
B::destructor: object at 0x9513008 -- A::destructor v == 100

+++ C::operator delete


*** constructor of C threw ***