Overloaded virtual method not being called

Started by
12 comments, last by Red Ant 14 years, 10 months ago
I've been debuging this for a while and I don't seem to notice what I'm doing wrong... I have a base class:

class cgui_object
{
    protected:
        cgui_object ( void );

    public:
        virtual void on_draw () {}
};


and a derived class:

class cgui_box : public cgui_object
{
    public:
        cgui_box ( void );

        virtual void on_draw (); // which is defined in the cpp, it just couts
};


Then I have a list of cgui_objects that gets iterated and the method on_draw is called from within cgui_object:

void cgui_object::draw()
{
	// Don't draw if not initialized
	if(!pgui || !visible) return;

	prenderer->set_orthographic_pixels(&viewport);

	prenderer->push_attribute_all();
	on_draw(); // This line gets executed every pass.
	prenderer->pop_attribute_all();

	children.move_first();
	while (!children.eof())
	{
		children.value().draw();
		children.move_next();
	}
}


cgui_object::on_draw() gets executed, but the overloaded on_draw() method in cgui_box is not. Any ideas? EDIT: Yes, cgui_box is of base cgui_object
[size="2"]I like the Walrus best.
Advertisement
The problem seems to be that the container I'm storing the base objects is of type <base> instead of <base*>. If I copy the derived-base instead of using a pointer, the overloaded function doesn't get called. I don't really understand why thouhg...
[size="2"]I like the Walrus best.
Sounds like it might be the same problem that was recently discussed here, specifically 'object slicing' (I could be wrong about that though).
yep, seems to be that.

Why, oh why can't we just have:
int main(){    derived d;    base b = d;    b.draw();    return 0;}


Working with polimorphism?
[size="2"]I like the Walrus best.
Dynamic dispatch only operates through pointers and references in C++, because a non-pointer non-reference can never be anything but its static type, and thus no dynamic dispatch is necessary or possible.

What you just posted slices the object. A derived is a base, but a base is not a derived.

Quote:Original post by jpetrie
Dynamic dispatch only operates through pointers and references in C++, because a non-pointer non-reference can never be anything but its static type, and thus no dynamic dispatch is necessary or possible.


I can see that now. To me polimorphism in c++ feels a little bit more hackish now than before. I can give virtual functions to a class but they won't be virtual at all when the instance is static. bleh.
[size="2"]I like the Walrus best.
You have the same situation in languages like C# or Java. When you say
Base b = new Derived();

b is actually a pointer to a derived, you just don't have to write it out.
(Assuming Base and Derived are classes and not structs in C#.)

By the way, we're talking about "overriding", not "overloading".

[Edited by - DevFred on June 6, 2009 4:58:38 AM]
Quote:Original post by owl
I can see that now. To me polimorphism in c++ feels a little bit more hackish now than before. I can give virtual functions to a class but they won't be virtual at all when the instance is static. bleh.


Hackish? Why? The language did exactly what one would expect it to do. You had an object of type cgui_object, so the language correctly chose the cgui_object::on_draw() implementation when you called on_draw(). There's nothing hackish about that.

I think you still haven't quite understood what the actual problem is. Since your container holds actual cgui_object objects rather than pointers to cgui_object objects, what happened when you tried to put an instance of cgui_box into the container is that a cgui_object got copy-constructed from a cgui_box. Understand? A __cgui_object__ got constructed, NOT a cgui_box.

My apologies if I assumed wrong, and you had actually already understood that.
The part I don't like is that if you create a static instance of the derived class and you do Base* b = &Derived, polimorphism works.

As jpetrie said, the language works like that and I've to get used to it.
[size="2"]I like the Walrus best.
You have to think about what it means to have an instance of an object; it means that at some location there are sizeof(cgui_object) bytes that make up that instance, amongst other things.

If polymorphism was to work on instances and a cgui_object could actually be any of it's subclasses how would anyone know how much memory to allocate for it (at compile time)? How could you have an array of cgui_objects where each element takes up a different amount of space?

Technically a language could allow for it, but then you would have all sorts of things having to be calculated at runtime instead of being known at compile time, and lots of trickery when it comes to iteration, and probably many more complications that I'm not thinking of at the moment.

This topic is closed to new replies.

Advertisement