Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!island!lars From: lars@island.COM (Lars Nyman) Newsgroups: comp.lang.c++ Subject: Re: multiple inheritance bug Keywords: multiple inheritance, virtual base classes Message-ID: <3662@island.COM> Date: 7 Feb 91 00:11:25 GMT References: <3553@island.COM> <9592@dog.ee.lbl.gov> Reply-To: lars@island.COM (Lars Nyman) Organization: Island Graphics, Marin County, California Lines: 58 In article <9592@dog.ee.lbl.gov> beard@ux5.lbl.gov (Patrick C Beard) writes: #In article <3553@island.COM> lars@island.COM (Lars Nyman) writes: ## ##I have a problem with multiple inheritance using virtual base classes, and ##suspect it's a bug in the C++ compiler. # #Don't be so quick to call this a bug. It's actually a feature. C++ does #not officially support the calling of virtual functions from a constructor. ARM Section 10.9c, page 233: "The first point at which C::f() can be called as f() is the first statement in the constructor C::C()". Thus, C++ "officially" supports calling virtual functions from a constructor. #The reason? If you are in the base class constructor of a derived class, #and you call a virtual function, if it called a function that is defined in #the derived class, that function would be passed a pointer to an incompletely #constructed derived object. As my example stated, I do not call a virtual function from the constructor of the base class. I call a virtual function (indirectly) from the constructor of the derived class. The call of the virtual function in the derived class occurs from function member (not constructor) of the base class. The problem is that the constructor of the derived class installs an incorrect vtable in the base class part of itself, so the base class cannot transform itself to a derived class (i.e. the offsets in the vtable is incorrect). # #Three level hierarchy: Base, Derived, MostDerived. # #class Base { ... } #class Derived : virtual Base { ... } #class MostDerived : Derived, Mixin { ... } # When Derived's constructor exits, MostDerived's constructor will install a new (correct) vtable in the base class part of itself. And things will work fine again. Until, it is time to destruct the MostDerived object. Then again, Derived's destructor will install an incorrect vtable in the Base part. #My philosophy is that constructors are for initialization. They should #perform no work. That is deferred until the object is completely #initialized. I find that this makes my designs much more robust. To completely initalize an object, you might very well have to perfrom work. And the right place to do that is of course in the constructor. A destructor might want to notify others that it is about to die - they might want to remove some references to the dying object. Note, the object is not yet dead when we enter the destructor; it doesn't cease to exist until the destructor exits. Lars Nyman