virtual member function in constructor

K

Karsten Hochkirch

Hi,

I have just encountered a problem when calling a virtual member function
in a constructor.
Only the memberfunction of the parent class is called instead of the
overloaded function.

I have attached a small example.

Is that bug or feature. If feature: is there an easy way to get the
behaviour as I am looking for?

Thanks

Karsten



#include <iostream>
using namespace std;
class A {
public:

virtual A(){init();}
virtual ~A(){}
virtual void init(){
cout << "class A::init\n";
}
void test(){init();}

};

class B: public A{
public:
B():A(){}
virtual ~B(){}
virtual void init(){
cout << "class B::init\n";
}
};

int main(int,char**){


// only class A's init is called
B b;

// works as I expected
b.test();
return 0;

}
 
K

Karsten Hochkirch

Oops,

the 'virtual' in front of the constructor was just desparate try I
forgot to remove before attaching the file...
 
R

Ron Natalie

Karsten Hochkirch said:
Is that bug or feature. If feature: is there an easy way to get the
behaviour as I am looking for?

That is the way it is supposed to work. For the duration of the execution of the
the constructor body, the dynamic type of the object is considered to be that of
the constructor that is running. The primary reason is that the derived class has
yet to be initialized (the base class constructor is run first), so you don't want to
be roaming around in the derived code.

The work around is to place any virtual function based common initialization in
a base class member function other than the constructor and then call it from
the derived constructor.

The same thing happens for destructors (just in the reverse order).
 
?

=?ISO-8859-1?Q?Le_G=E9ant_Vert?=

Karsten said:
Oops,

the 'virtual' in front of the constructor was just desparate try I
forgot to remove before attaching the file...
this is not really a feature, this is the way things are supposed to
happen... When the constructor's called, the object does not exist yet :
so the code of your overloaded virtual method is unknown and unreachable
; thus, only the one of the parent class can be called.
(a funny thing you can do once you've understood this, is to use it to
call code of a pure virtual method)
the tip I'd told you is to never call any method in a constructor, and
if needed, to provided an init() that should be called by the programmer
(not as you're doing in your code sample, where init() is called from
the ctor)
 
J

Jonathan Turkanis

Karsten Hochkirch said:
Hi,

I have just encountered a problem when calling a virtual member function
in a constructor.

Within a constructor, virtual calls are resolved using the vtable of
the class in which the constructor is defined, rather than the vtable
of the fully derived type of the object being constructed. Therefore,
you must be very careful when calling virtual functions from
constructors; in particular, the possibility of calling a pure virtual
function exists.

Jonathan
 
A

Alf P. Steinbach

[Correct explanation of why, snipped.]

See also the FAQ:
<url: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.3>


The work around

Actually there are many different workarounds.

The most common workarounds are also in the FAQ (I'm happy to take much credit
for their inclusion, although credit for the text goes to Marshall Cline):

<url: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.4>


is to place any virtual function based common initialization in
a base class member function other than the constructor and then call it from
the derived constructor.

This only seems to allow virtuality for one level of class derivation.

It's not a commonly used workaround.

I don't recommend it, but perhaps it should be included among the others in
the FAQ?
 
D

David Harmon

I have just encountered a problem when calling a virtual member function
in a constructor.
Only the memberfunction of the parent class is called instead of the
overloaded function.

This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[23.3] When my base class's constructor calls a virtual function on its
this object, why doesn't my derived class's override of that virtual
function get invoked?" It is always good to check the FAQ before
posting. You can get the FAQ at:
http://www.parashift.com/c++-faq-lite/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,159
Messages
2,570,886
Members
47,419
Latest member
ArturoBres

Latest Threads

Top