home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / lang / cplus / 19818 < prev    next >
Encoding:
Text File  |  1993-01-24  |  2.5 KB  |  132 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!uchdcc!gschwarz
  3. From: gschwarz@dcc.uchile.cl (Guillermo Schwarz Utrup)
  4. Subject: Virtual function call within constructors
  5. Originator: gschwarz@trauco
  6. Sender: usenet@dcc.uchile.cl (Network News)
  7. Message-ID: <1993Jan24.051330.3721@dcc.uchile.cl>
  8. Date: Sun, 24 Jan 1993 05:13:30 GMT
  9. Nntp-Posting-Host: trauco.dcc.uchile.cl
  10. Organization: Universidad de Chile, Depto. de Ciencias de la Computacion
  11. Lines: 120
  12.  
  13.  
  14. I have found that virtual functions are not handled as one could expect
  15. when called from a constructor.
  16.  
  17. I proved the following code in SCO C++, Turbo C++ and G++:
  18.  
  19. -- cut here --
  20. #include <stdio.h>
  21.  
  22. class Base
  23. {
  24.   public:
  25.     Base();
  26.     virtual void Vtl();
  27. };
  28.  
  29. class Derived : public Base
  30. {
  31.   public:
  32.     Derived();
  33.     virtual void Vtl();
  34. };
  35.  
  36. Base::Base()
  37. {
  38.    Vtl();  // this call should be virtual
  39. }
  40.  
  41. void Base::Vtl()
  42. {
  43.    printf( "Base::Vtl()\n" );
  44. }
  45.  
  46. Derived::Derived()
  47. {
  48.    Vtl();
  49. }
  50.  
  51. void Derived::Vtl()
  52. {
  53.    printf( "Derived::Vtl()\n" );
  54. }
  55.  
  56. main()
  57. {
  58.     Base b;
  59.     Derived d;
  60. }
  61. -- cut here --
  62.  
  63. The object b constructor should call Base::Vtl(). It works.
  64. The object D constructor calls object b constructor which in turn has
  65. to call virtual method Vtl(), that is to say: Derived::Vtl(). It doesn't work.
  66. Then object D constructor calls virtual method Vtl() directly, that is to
  67. say: Derived::Vtl(). Of course, this part works.
  68.  
  69. The result should then be:
  70. Base::Vtl()
  71. Derived::Vtl()
  72. Derived::Vtl()
  73.  
  74. But actually the output is:
  75. Base::Vtl()
  76. Base::Vtl()
  77. Derived::Vtl() 
  78.  
  79. Well, it doesn't work as one would think. If the method is virtual,
  80. why the constructor circumvents the correct way of calling?
  81.  
  82. I tried an equivalent code in Turbo Pascal 5.5:
  83.  
  84. program Virtual_Test;
  85.  
  86. type
  87.     Base = object
  88.               constructor Init;
  89.               procedure Vtl; virtual;
  90.             end;
  91.     Derived = object
  92.               constructor Init;
  93.               procedure Vtl; virtual;
  94.             end;
  95.  
  96. constructor Base.Init;
  97. begin
  98.       Vtl;
  99. end;
  100.  
  101. procedure Base.Vtl;
  102. begin
  103.       writeln( "Base.Vtl" );
  104. end;
  105.  
  106. constructor Derived.Init;
  107. begin
  108.       Base.Init;
  109.       Vtl;
  110. end;
  111.  
  112. procedure Derived.Vtl;
  113. begin
  114.       writeln( "Derived.Vtl" );
  115. end;
  116.  
  117. var
  118.     b :Base;
  119.     d :Derived;
  120.  
  121. begin { main }
  122.      b.Init;
  123.      d.Init;
  124. end.
  125.  
  126. Believe it or not this works as expected.
  127. -- 
  128.      _                           The difference between a shallow copy
  129.  _  (_   _ |_        _    _ _    and a deep copy is that the first is
  130. (_)  _) (_ | | \/\/ (_)\ |  _)   less happy than your mother.
  131.   )                          )
  132.