D pointers #2

Bongani Hlope bhlope at mweb.co.za
Thu Oct 20 05:40:24 BST 2005


On Thursday 20 October 2005 00:25, Maks Orlovich wrote:
> On Wednesday 19 October 2005 18:03, Guillaume Laurent wrote:
> > On Wednesday 19 October 2005 23:53, Michael Pyne wrote:
> > > Now I could be thinking things wrong here, but if I know my obscure C++
> > > correctly, nothing is virtual in nature within the constructor of a
> > > class.
> >
> > You're correct.
>
> Not quite. Try out the following:
>
> #include <iostream>
>
> struct A
> {
>         A() {
> 		doStuff();
>         }
>
> 	void doStuff(){
> 		virt();
> 	}
>
> 	virtual void virt() {
> 		std::cout << "A\n";
> 	}
> };
>
> struct B: public A
> {
>         B() {
> 		doStuff();
>         }
>
> 	virtual void virt() {
> 		std::cout << "B\n";
> 	}
> };
>
> struct C: public B
> {
>         C() {
> 		doStuff();
>         }
>
> 	virtual void virt() {
> 		std::cout << "C\n";
> 	}
> };
>
> int main() {
> 	C test;
> }
>
> ---
> It outputs A, B, C. If virtuals didn't work, it would output A, A, A.
> In fact, virtuals very much work inside the constructor --- except that
> when you're in a constructor of a superclass, your class -is- the
> superclass.
>

And it is not calling the "virtual" version of those methods.  

<quote from="Thinking in C++">
Inside any constructor, the object may only be partially formed – you can only 
know that the base-class objects have been initialized, but you cannot know 
which classes are inherited from you. A virtual function call, however, 
reaches “forward” or “outward” into the inheritance hierarchy. It calls a 
function in a derived class. If you could do this inside a constructor, you’d 
be calling a function that might manipulate members that hadn’t been 
initialized yet, a sure recipe for disaster.

The second reason is a mechanical one. When a constructor is called, one of 
the first things it does is initialize its VPTR. However, it can only know 
that it is of the “current” type – the type the constructor was written for. 
The constructor code is completely ignorant of whether or not the object is 
in the base of another class. When the compiler generates code for that 
constructor, it generates code for a constructor of that class, not a base 
class and not a class derived from it (because a class can’t know who 
inherits it). So the VPTR it uses must be for the VTABLE of that class. 
</quote>





More information about the kde-core-devel mailing list