Sign in to follow this  
polyfrag

Virtual base-class method called instead of derived-class method

Recommended Posts

polyfrag    2502

All my other derived-class methods are called correctly but this one isn't for some reason.

class Widget
{
public:
	//...
	
	virtual void draw()	{}
	virtual void draw2()	{}
	virtual void frameupdate()	{ /* g_log<<"widg frameup"<<endl; g_log.flush(); */ }
	//...
};

class EditBox : public Widget
{
public:
	//...
	void draw();
	//...
	void frameupdate();
	//...
};

#define MOUSESC_DEBUG

void EditBox::frameupdate()
{
#ifdef MOUSESC_DEBUG
	g_log<<"editbox frameup"<<endl;
	g_log.flush();
#endif

	//...
}

class View
{
	//...

	void frameupd()
	{
		//g_log<<"view frameup"<<endl;
		//g_log.flush();

		for(auto i=widget.begin(); i!=widget.end(); i++)
			(*i)->frameupdate();
	}

	//...
};

The View calls frameupdate(); on each member widget, none of which are the base class (all are some derived type) and some are EditBox type.

 

Views output "view frameup" to the log.

 

The base class method frameupdate(); outputs "widg frameup" to the log.

 

The EditBox derived class outputs "editbox frameup".

 

What I can see in the log is "view frameup" and "widg frameup" but no "editbox frameup". The derived frameupdate(); method isn't being called. What the heck?

 

 

Share this post


Link to post
Share on other sites
SiCrane    11839

Are you storing your widgets by value or by pointer? If by value, then you've probably got a slicing issue going on.

Share this post


Link to post
Share on other sites

I see an 'auto' in there, so you're using C++11, right? . This means you probably have access to the 'override' keyword, which you should use when overriding virtual functions, because then the compiler will explicitly warn you (at compile time) if there's any accidental mis-matches in function signatures, which sometimes accidentally results in what you're encountering.

 

(I don't know if the function signatures were "cleaned up" or not when you posted)

 

For example, if:

Base:
virtual void frameupdate() const

Derived:
void frameupdate() //not-const

It won't properly be overridden, because the second frameupdate() is actually a different function signature because of the lack of const.

 
Another non-related tip is that you could re-write your for() loop like this:

for(Widget *widget : this->widgets)
{
    widget->frameupdate();
}
Edited by Servant of the Lord

Share this post


Link to post
Share on other sites
wqking    761

Are you storing your widgets by value or by pointer? If by value, then you've probably got a slicing issue going on.

He uses (*it)-> to access the member so the widgets should be stored by pointer.

Share this post


Link to post
Share on other sites

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