Sign in to follow this  

Constructor calling a virtual method

This topic is 3586 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! I simplified my problem a bit, so it is easier to understand. I have a simple base class with a certain virtual method. The constructor of that class calls the method and that's all. Now I derive another class from that base class which overrides the virtual method. What I expected when initializing the derived class was to get the output from the derived method. In fact the method from the base class was called. I think this behaviour is quite astonishing and therefore I just wanted to know why that happens and how I can fix this. A small example:
#include <stdio.h>

struct ClassDay
{
	virtual void say();
	ClassDay();
};

struct ClassMorning : ClassDay
{
	virtual void say();
};

void ClassMorning::say(){ printf("Good morning!"); }
void ClassDay::say(){ printf("Hello!"); }

ClassDay::ClassDay(){ say(); }

void main()
{

	ClassMorning test;
	getchar();

}
I hope you can help :)

Share this post


Link to post
Share on other sites
This is intended behavior. When the base class constructor is being run, virtual function calls will use the base class versions. The reason for this is that derived class functions may access data members that don't exist in the base class. Ex:

struct Base {
Base() { f(); }
virtual void f(void) {}
};

struct Derived : Base {
std::string data;
void f(void) { data = "fred"; }
}

What happens if Derived::f() is called in the Base class? data hasn't been constructed yet, so the assignment may die a horrible death.

Share this post


Link to post
Share on other sites
I think I know the reason for this behaviour now. It is logical that the base constructor does not know anything about the children's methods, because it is called before the children's constructors. Therefore it calls the known method and the derived one is ignored.

Nevertheless I have no idea how to cope with the problem...

Share this post


Link to post
Share on other sites
The .net c# compiler issues a warning when you call a virtual method from the constructor. Embarrassingly enough, our currently project at work heavily shows this bad practice (and at least some of the fault is mine :-(
We have had a few problems with it (now addresed) and thus I highly encourage to avoid that at all.

My 2 cents.

Share this post


Link to post
Share on other sites
This is as expected. ClassMorning haven't been constructed yet, so its generally not safe to call it if it would be possible. I refer to c++ faq lite.

http://new-brunswick.net/workshop/c++/faq/ctors.html#faq-10.7

"Here is something that never works: the {body} of a constructor (or a function called from the constructor) cannot get down to a derived class by calling a virtual member function that is overridden in the derived class. If your goal was to get to the overridden function in the derived class, you won't get what you want. Note that you won't get to the override in the derived class independent of how you call the virtual member function: explicitly using the this pointer (e.g., this->method()), implicitly using the this pointer (e.g., method()), or even calling some other function that calls the virtual member function on your this object. The bottom line is this: even if the caller is constructing an object of a derived class, during the constructor of the base class, your object is not yet of that derived class. You have been warned."

Workaround would be to pass the data that is needed from the derived class or to write your own init method which you call after construction.

Share this post


Link to post
Share on other sites

This topic is 3586 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this