home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: sparky!uunet!uchdcc!gschwarz
- From: gschwarz@dcc.uchile.cl (Guillermo Schwarz Utrup)
- Subject: Virtual function call within constructors
- Originator: gschwarz@trauco
- Sender: usenet@dcc.uchile.cl (Network News)
- Message-ID: <1993Jan24.051330.3721@dcc.uchile.cl>
- Date: Sun, 24 Jan 1993 05:13:30 GMT
- Nntp-Posting-Host: trauco.dcc.uchile.cl
- Organization: Universidad de Chile, Depto. de Ciencias de la Computacion
- Lines: 120
-
-
- I have found that virtual functions are not handled as one could expect
- when called from a constructor.
-
- I proved the following code in SCO C++, Turbo C++ and G++:
-
- -- cut here --
- #include <stdio.h>
-
- class Base
- {
- public:
- Base();
- virtual void Vtl();
- };
-
- class Derived : public Base
- {
- public:
- Derived();
- virtual void Vtl();
- };
-
- Base::Base()
- {
- Vtl(); // this call should be virtual
- }
-
- void Base::Vtl()
- {
- printf( "Base::Vtl()\n" );
- }
-
- Derived::Derived()
- {
- Vtl();
- }
-
- void Derived::Vtl()
- {
- printf( "Derived::Vtl()\n" );
- }
-
- main()
- {
- Base b;
- Derived d;
- }
- -- cut here --
-
- The object b constructor should call Base::Vtl(). It works.
- The object D constructor calls object b constructor which in turn has
- to call virtual method Vtl(), that is to say: Derived::Vtl(). It doesn't work.
- Then object D constructor calls virtual method Vtl() directly, that is to
- say: Derived::Vtl(). Of course, this part works.
-
- The result should then be:
- Base::Vtl()
- Derived::Vtl()
- Derived::Vtl()
-
- But actually the output is:
- Base::Vtl()
- Base::Vtl()
- Derived::Vtl()
-
- Well, it doesn't work as one would think. If the method is virtual,
- why the constructor circumvents the correct way of calling?
-
- I tried an equivalent code in Turbo Pascal 5.5:
-
- program Virtual_Test;
-
- type
- Base = object
- constructor Init;
- procedure Vtl; virtual;
- end;
- Derived = object
- constructor Init;
- procedure Vtl; virtual;
- end;
-
- constructor Base.Init;
- begin
- Vtl;
- end;
-
- procedure Base.Vtl;
- begin
- writeln( "Base.Vtl" );
- end;
-
- constructor Derived.Init;
- begin
- Base.Init;
- Vtl;
- end;
-
- procedure Derived.Vtl;
- begin
- writeln( "Derived.Vtl" );
- end;
-
- var
- b :Base;
- d :Derived;
-
- begin { main }
- b.Init;
- d.Init;
- end.
-
- Believe it or not this works as expected.
- --
- _ The difference between a shallow copy
- _ (_ _ |_ _ _ _ and a deep copy is that the first is
- (_) _) (_ | | \/\/ (_)\ | _) less happy than your mother.
- ) )
-