home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / cplus / 12393 < prev    next >
Encoding:
Text File  |  1992-08-15  |  3.6 KB  |  134 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!cs.utexas.edu!asuvax!ennews!enuxha.eas.asu.edu!nwatson
  3. From: nwatson@enuxha.eas.asu.edu (Nathan F. Watson)
  4. Subject: BCC:  virtual function calls from constructor/destructor
  5. Message-ID: <1992Aug16.090135.6753@ennews.eas.asu.edu>
  6. Sender: news@ennews.eas.asu.edu (USENET News System)
  7. Organization: Arizona State University
  8. Date: Sun, 16 Aug 1992 09:01:35 GMT
  9. Lines: 123
  10.  
  11.  
  12. I ran into a problem with virtual functions today when using my
  13. new C++ compiler (Borland C++ 3.1).
  14.  
  15. The scenario is as follows:
  16.    * classes A and B are defined, and B is derived from A;
  17.    * A's constructor calls a virtual function A::vfunc().  B::vfunc()
  18.      is also defined.
  19.  
  20. An unexpected (though perhaps not unreasonable) thing happens when I
  21. try to construct an object of class B.  A::A() is called first, which
  22. then calls the virtual function A::vfunc().  I would expect use of
  23. B::vfunc().  However, A::A() calls A::vfunc().
  24.  
  25. Later in the program, I call vfunc() for an object of type B.  B::vfunc()
  26. is used, as expected.
  27.  
  28. A quick look at the Borland C++ and Stroustrup books did not bring
  29. enlightenment.  Is BCC behaving appropriately?  I suppose a call
  30. to B::vfunc() within A::A() might not make sense because the B class'
  31. portion of the object has not yet been constructed.  Does Stroustrup
  32. specifically mention this case?
  33.  
  34. The following code and output illustrate the situation described above.
  35. If you have any insight, please mail me at nwatson@enuxha.eas.asu.edu.
  36. Thank you.
  37.  
  38.  
  39. // ---------- try.cpp
  40.  
  41. #include <iostream.h>
  42. #include <fstream.h>
  43.  
  44. static ofstream ostr;
  45.  
  46. class A {
  47.       int dummy;
  48.    public:
  49.       virtual void vfunc();
  50.    public:
  51.       A();
  52.       virtual ~A();
  53.       void indirect_vfunc();      // Indirect call to vfunc().
  54. };
  55. void A::vfunc()
  56.    { ostr << "A::vfunc()" << endl; }
  57. A::A()
  58.    { ostr << "A::A()" << endl; vfunc(); }
  59. A::~A()
  60.    { ostr << "A::~A()" << endl; vfunc(); }
  61. void A::indirect_vfunc()
  62.    { ostr << "A::indirect_vfunc()" << endl; vfunc(); }
  63.  
  64. class B : public A {
  65.    public:
  66.       void vfunc();
  67.    public:
  68.       B();
  69.       ~B();
  70. };
  71. void B::vfunc()
  72.    { ostr << "B::vfunc()" << endl; A::vfunc(); }
  73. B::B() : A()
  74.    { ostr << "B::B()" << endl; }
  75. B::~B()
  76.    { ostr << "B::~B()" << endl; }
  77.  
  78. int main(int, char *[])
  79. {
  80.    ostr.open("try.out");
  81.    {
  82.       ostr << "---------- try.cpp output" << endl;
  83.       ostr << "*** Constructing a" << endl;
  84.       A a;
  85.       ostr << "*** Constructing b" << endl;
  86.       B b;
  87.       ostr << "*** a.vfunc()" << endl;
  88.       a.vfunc();
  89.       ostr << "*** b.vfunc()" << endl;
  90.       b.vfunc();
  91.       ostr << "*** a.indirect_vfunc()" << endl;
  92.       a.indirect_vfunc();
  93.       ostr << "*** b.indirect_vfunc()" << endl;
  94.       b.indirect_vfunc();
  95.       ostr << "*** End (destructors)" << endl;
  96.    }
  97.    ostr.close();
  98.    return 0;
  99. }
  100.  
  101. ---------- try.cpp output
  102. *** Constructing a
  103. A::A()
  104. A::vfunc()
  105. *** Constructing b
  106. A::A()
  107. A::vfunc()              <---- call of B::vfunc() expected.  ERROR?
  108. B::B()                        (It is true that "B" class not yet constructed.)
  109. *** a.vfunc()
  110. A::vfunc()
  111. *** b.vfunc()
  112. B::vfunc()              <---- B::vfunc() (calls A::vfunc()) called.
  113. A::vfunc()
  114. *** a.indirect_vfunc()
  115. A::indirect_vfunc()
  116. A::vfunc()
  117. *** b.indirect_vfunc()
  118. A::indirect_vfunc()     <---- indirect calls works.
  119. B::vfunc()
  120. A::vfunc()
  121. *** End (destructors)
  122. B::~B()
  123. A::~A()
  124. A::vfunc()              <---- Destructor also calls only A::vfunc().  ERROR?
  125. A::~A()                       (It is true that "B" class has been destroyed.)
  126. A::vfunc()
  127.  
  128.  
  129.  
  130. --
  131. ---------------------------------------------------------------------
  132. Nathan F. Watson                             Arizona State University
  133. nwatson@enuxha.eas.asu.edu                Computer Science Department
  134.