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

  1. Xref: sparky comp.lang.c++:17828 comp.std.c++:1749
  2. Newsgroups: comp.lang.c++,comp.std.c++
  3. Path: sparky!uunet!Cadence.COM!usenet
  4. From: cox@cadence.com (Henry Cox)
  5. Subject: Virtual base classes and mem initializers
  6. Message-ID: <1992Dec11.165754.9910@Cadence.COM>
  7. Followup-To: comp.std.c++
  8. Summary: Either I do not undertand or I do not like the way this is handled
  9. Keywords: mem initializers, virtual base classes, multiple inheritance
  10. Sender: usenet@Cadence.COM (Usenet News)
  11. Nntp-Posting-Host: acae206
  12. Organization: Cadence Design Systems. Lowell MA
  13. Date: Fri, 11 Dec 1992 16:57:54 GMT
  14. Lines: 131
  15.  
  16. (I posted this last night - it did not appear on our systems, so I am
  17. posting it a second time.  I apologize for any duplication you see.)
  18.  
  19. I ran into an interesting situation with respect to multiple
  20. inheritance and virtual base classes.  The following example
  21. illustrates the problem:
  22.  
  23. class A {
  24.   A(int) { /*... */ ; }
  25. };
  26.  
  27. class B : virtual public A {
  28.   B(int a, int b) : A(a) { /* ... */ ; }
  29. };
  30.  
  31.  
  32. class C : virtual public A {
  33.   C(int a, int c) : A(a) { /* ... */ ; }
  34. };
  35.  
  36.  
  37. class D : public B, public C {
  38.   D(int a, int b, int c, int d) : A(a), B(a,b), C(a,c) { /* ... */; }
  39. }
  40.  
  41.  
  42. class E : public D {
  43. #ifdef WIBNI /* [1] */  
  44.      // what I would LIKE to be able to do
  45.   E(int a, int b, int c, int d, int e) : D(a,b,c,d) { /* ... */; }
  46. #else
  47.      // what I actually HAVE to do
  48.   E(int a, int b, int c, int d, int e) : A(a),D(a,b,c,d) { /* ... */; }
  49. #endif
  50. }
  51.  
  52. /* [1] Wouldn't It Be Nice If */
  53.  
  54. The English explanation:  My inheritance graph is as follows:
  55.  
  56.             A
  57.        / \
  58.           B   C
  59.        \ /
  60.         D
  61.         |
  62.         E
  63.  
  64. "A" is a virtual base class of "B" and "C".  "A" does not have a
  65. default constructor (my application is a bit more involved than the
  66. above).
  67.  
  68. "B" and "C" are base classes of "D".  I understand and support that
  69. "D"'s constructor(s) must specify how the virtual base class "A" is
  70. constructed.  (If this was not the case, there could be ambiguities in
  71. how "A" was actually constructed, given that the calls to "A"'s
  72. constructor from "B" and from "C" could be different.)  This is
  73. explained in the ARM S12.6.2, pp. 292--4.
  74.  
  75. What I don't understand is why "E" must also declare how the virtual
  76. base class "A" is to be constructed - shouldn't the compiler be able
  77. to figure out that the "virtualness" of "A" at "E" comes about at "D",
  78. and thus do the right thing:
  79.     1) try to construct a "D", the base class of "E"
  80.     2) note that "A" is a multiply-inherited virtual base class of
  81.        "D" - and thus that "A"'s constructor must be called with
  82.        the arguments as specified by "D"'s constructor ("A"'s
  83.        default constructor if none is declared).
  84.     3) construct "A"
  85.     4) try to construct "B" - the first base class of "D"
  86.     5) note that "A" is a virtual base class of "B" - note that
  87.        "A" has already been constructed - "B"'s "A" is done -
  88.        ignore)
  89.     6) execute "B"'s constructor
  90.     7) try to construct "C" - the second base class of "D"
  91.     5) note that "A" is a virtual base class of "C" - note that
  92.        "A" has already been constructed - "C"'s "A" is done -
  93.        ignore)
  94.     6) execute "C"'s constructor
  95.     7) execute "D"'s constructor
  96.     8) execute "E"'s constructor
  97.  
  98. I believe that the implemention (gcc 2.3.2 and sun C++ vers. 2.1) is
  99. bad in that anyone who uses class D, or any class derived from D, must
  100. know that _complete_ inheritance graph of their class in order to know
  101. which virtual base class constructors they must call.  (It is not
  102. sufficient that my code compiles, as, for example, default
  103. constructors may be called when I really want a different one...I just
  104. don't know that I want a different constructor until I understand the
  105. entire inheritance graph.)  If nothing else, this violates the
  106. object-oriented paradigm - at least as I understand it.
  107.  
  108.  
  109. What I propose, then is that the virtual base class constructor call
  110. be required _only_ at the apex of a multiple-inheritance cone.
  111. Otherwise, the compiler should figure it out, from the base classes,
  112. exactly as for a "normal" base class.
  113.  
  114.  
  115. For example
  116.  
  117. class F : public E, public C {
  118.    F(...) : A(...), E(...) { /*... */;}
  119.            /* A's constructor must be named, as F is
  120.               at the apex of an inheritance cone - it
  121.               contains only one copy of A, and I must
  122.               declare how that A is to be initialized */
  123. };
  124.  
  125.  
  126. class G: public F, public A {
  127.   G(...} : A(...), F(...) { /* ... */; }
  128.            /* G contains _two_ copies of A - one virtually,
  129.               from F, and one immediate (non-virtual).  A's
  130.               constructor is called to construct the immediate
  131.               one - the virtual one is constructed through F. */
  132. };
  133.  
  134.  
  135. Comments?  Suggestions?  
  136.  
  137. I would appreciate it if you would send replies via email in addition
  138. to posting them.  (Usually, I cannot keep up with the volume of these
  139. groups.) 
  140.  
  141. I will summarize and post any responses I receive. 
  142.  
  143. Thanks.
  144. --
  145.  
  146.                     Henry
  147.