ckl@SIRIUS.RISC.COM (Carl K. Lim) (08/21/90)
Hello. I have this problem: when I'm calling a virtual function from a parent class's constructor, it fails to execute the derived class's function. For example, in the following program, when B is declared, print() is called from A's constructor. But instead of looking up the B::print(), A::print() is called instead. Has anybody run into this kind of problem? Is there a way to get around it? #include <stdio.h> class A { public: A() { print(); } virtual void print() { printf("A\n"); } }; class B : public A { public: B() {} void print() { printf("B\n"); } }; int main() { B b; }
jbuck@galileo.berkeley.edu (Joe Buck) (08/21/90)
In article <9008201757.AA23899@sirius.risc.com>, ckl@SIRIUS.RISC.COM (Carl K. Lim) writes: |> Hello. I have this problem: when I'm calling a virtual function from a parent |> class's constructor, it fails to execute the derived class's function. This is a "feature" and is documented in Ellis and Stroustrup, which is the base document for the C++ standard. Why? Because in the base class constructor, the derived part of the object hasn't been constructed yet; it's in an undefined state. -- Joe Buck jbuck@galileo.berkeley.edu {uunet,ucbvax}!galileo.berkeley.edu!jbuck
brucec@phoebus.phoebus.labs.tek.com (Bruce Cohen;;50-662;LP=A;) (08/21/90)
In article <9008201757.AA23899@sirius.risc.com> ckl@SIRIUS.RISC.COM (Carl K. Lim) writes: > > > Hello. I have this problem: when I'm calling a virtual function from a parent > class's constructor, it fails to execute the derived class's function. For > example, in the following program, when B is declared, print() is called from > A's constructor. But instead of looking up the B::print(), A::print() is > called instead. Has anybody run into this kind of problem? Is there a way > to get around it? > > #include <stdio.h> > > class A > { > public: > A() { print(); } > virtual void print() { printf("A\n"); } > }; > > > class B : public A > { > public: > B() {} > void print() { printf("B\n"); } > }; > > > int main() > { > B b; > } What you are seeing is the way the language is specified to work: overloading of a virtual function is ignored when the function is called from a constructor. From the bible (Ellis & Stroustrup, "The Annotated C++ Reference Manual") page 294, scectio 12.7: "Member functions may be called in constructors and destructors. This implies that virtual functions may be called (directly or indirectly). The function called will be the oned defined in the constructor's (or destructor's) own class or its bases, but *not* [italics theirs] any functions overriding it in a derived class. This ensures that unconstructed objects will not be accessed during construction and destruction." That insurance is necessary because constructors are called in order from the base class out towards the derived class. To get the effect I think you want, put a print(); statement in B's constructor: class B : public A { public: B() { print(); } void print() { printf("B\n"); } }; If that's not good enough, then you'll have to change your main to: int main() { B b; b->print(); } -- --------------------------------------------------------------------------- NOTE: USE THIS ADDRESS TO REPLY, REPLY-TO IN HEADER MAY BE BROKEN! Bruce Cohen, Computer Research Lab email: brucec@tekcrl.labs.tek.com Tektronix Laboratories, Tektronix, Inc. phone: (503)627-5241 M/S 50-662, P.O. Box 500, Beaverton, OR 97077
jamshid@walt.cc.utexas.edu (Jamshid Afshar) (08/21/90)
I, too, encountered the problem of not being able to use virtual functions in a base class constructor. The only way I know around this is to either pass the information in the parameter list, or put the stuff which uses the virt.func. in a init() member function. I'm glad this came up because I posted an article to comp.std.c++ about this and have yet to receive any feedback. In the article I asked if it were possible to implement static virtual functions in C++. I have found the need for them several times. Passing stuff down a class hierarchy is a pain and it makes it hard to use inheritance when you want to change some parameter to a base class constructor farther down the line. I wrote out a scenario where I really needed them in the comp.std.c++ article, so please check it out. --Jamshid Afshar --jamshid@ccwf.cc.utexas.edu
jfw@rome.wpd.sgi.com (john fergus wilkinson) (08/21/90)
In article <9008201757.AA23899@sirius.risc.com>, ckl@SIRIUS.RISC.COM (Carl K. Lim) writes: > > Hello. I have this problem: when I'm calling a virtual function from a parent > class's constructor, it fails to execute the derived class's function. For > example, in the following program, when B is declared, print() is called from > A's constructor. But instead of looking up the B::print(), A::print() is > called instead. Has anybody run into this kind of problem? Is there a way > to get around it? > > #include <stdio.h> > > class A > { > public: > A() { print(); } > virtual void print() { printf("A\n"); } > }; > > > class B : public A > { > public: > B() {} > void print() { printf("B\n"); } > }; > > > int main() > { > B b; > } See Ellis and Stroustrup, Section 12.7.
jean@paradim.UUCP (Jean Pierre LeJacq) (08/21/90)
In article <9008201757.AA23899@sirius.risc.com>, ckl@SIRIUS.RISC.COM (Carl K. Lim) writes: > > Hello. I have this problem: when I'm calling a virtual function from a parent > class's constructor, it fails to execute the derived class's function. For > ... Virtual member functions can be called in constructors but the function called will be the one defined in the constructor's own class. This rule prevents access to partially constructed objects. See [E&S: 294]. This also applies to destructors.
gwu@nujoizey.tcs.com (George Wu) (08/22/90)
This question has been asked before. According to Stanley Lippman's "C++ Primer," virtual functions called from the constructor or destructor of a base class will call the virtual function defined in the base class. This is by definition of the C++ language. The explanation is that at construction time, the derived object will not yet be constructed, so the function cannot be from the derived class. Likewise, in the destructor, the derived class will have already been destroyed. George ---- George J Wu | gwu@tcs.com or ucbcad!tcs!gwu Software Engineer | 2121 Allston Way, Berkeley, CA, 94704 Teknekron Communications Systems, Inc.| (415) 649-3752