home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / lang / cplus / 18022 < prev    next >
Encoding:
Text File  |  1992-12-15  |  3.2 KB  |  115 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!microsoft!hexnut!jimad
  3. From: jimad@microsoft.com (Jim Adcock)
  4. Subject: Re: Overriding the order of constructors?
  5. Message-ID: <1992Dec15.191248.24996@microsoft.com>
  6. Date: 15 Dec 92 19:12:48 GMT
  7. Organization: Microsoft Corporation
  8. References: <1992Dec13.220943.22047@jarvis.csri.toronto.edu> <robison1.724307343@husc10> <Bz8oGx.B7x@well.sf.ca.us>
  9. Keywords: constructor ordering
  10. Lines: 103
  11.  
  12. In article <Bz8oGx.B7x@well.sf.ca.us> johnrp@well.sf.ca.us (John Panzer) writes:
  13. |In article <robison1.724307343@husc10> robison1@husc10.harvard.edu (Keith Robison) writes:
  14. |>    I believe you can effectively accomplish this dangerous
  15. |>goal by calling virtual functions in your constructors:
  16. |>
  17. |>
  18. |>class A {
  19. |>  A() { reroute(); do_A_ctor_stuff(); }
  20. |>  virtual void reroute(); { }
  21. |>}
  22. |>
  23. |>class B : public A {
  24. |>  B() {}
  25. |>  void reroute ()  { do_B_ctor_stuff(); }
  26. |>}
  27. |>
  28. |>
  29. |>This will cause B's reroute() to be executed before any 
  30. |>A constructing has occurred.
  31. |>
  32. |
  33. |Are you certain?  I believe that A::reroute() will
  34. |be called if reroute() is called from within A's
  35. |constructor or destructor.  I think this is a
  36. |common C++ "gotcha" - it's certainly gotten me
  37. |in the past.
  38.  
  39. Before  A::A() is executed on your object, your object is only
  40. a bag o' bits.  It is only a bag o' bits.
  41.  
  42. When A::A() begins executing on your object, your object becomes
  43. an A.  It may not be a fully formed A, because fully forming A
  44. is your job inside A::A().
  45.  
  46. When B::B() begins executing on your object, your object becomes
  47. an B.  It may not be a fully formed B, because fully forming B
  48. is your job inside B::B().
  49.  
  50. ....
  51.  
  52. When B::~B() begins executing on your object, your object becomes
  53. an B.  It may not be a fully deformed B, because fully deforming B
  54. is your job inside B::~B().
  55.  
  56. When A::~A() begins executing on your object, your object becomes
  57. an A.  It may not be a fully deformed A, because fully deforming A
  58. is your job inside A::~A().
  59.  
  60. After A::~A() executes on your object, your object is only a
  61. bag o' bits.
  62.  
  63. ======
  64.  
  65. In the case of constructors/destructors of objects with virtual functions,
  66. compilers typically *actually* implement these "type changes" of your
  67. object, as it is being formed or deformed by its various constructors
  68. or destructors, *by dynamically changing your object vtable pointer[s]*.
  69. If you haven't actually looked at the assembly code generated for some
  70. simple constructors/destructors and inheritence, its well worth the
  71. exercise!  There be dragons!
  72.  
  73. [Note that compilers have been known to screw this stuff up.]
  74.  
  75. Below find a little hack program that may ;-) demonstrate modification
  76. of the vtable ptrs during construction / destruction on your system:
  77.  
  78. #include <stdio.h>
  79.  
  80. class A
  81. {
  82. public:
  83.     virtual void print();
  84.     virtual int size();
  85.     A() { printf(" A() "); print(); }
  86.     virtual ~A() { printf("~A() "); print(); }
  87. };
  88.  
  89. void A::print()
  90. {
  91.     for (int i=0; i<size(); ++i)
  92.         printf("%02X ", (unsigned)*(((unsigned char*)this)+i));
  93.     printf("\n");
  94. }
  95.  
  96. int A::size() { return sizeof(A); }
  97.  
  98. class B : public A
  99. {
  100.     long L;
  101. public:
  102.     virtual int size();
  103.     B() : L(0x12345678) { printf(" B() "); print(); }
  104.     virtual ~B() { L = 0x55555555; printf("~B() "); print(); }
  105. };
  106.  
  107. int B::size() { return sizeof(B); }
  108.  
  109. main()
  110. {
  111.     B b;
  112.  
  113.     return 0;
  114. }
  115.