Sign in to follow this  
flobadob

Virtual functions and recursion

Recommended Posts

I have a scene graph with lots of classes derived from CSceneNode. The default render function 'virtual HRESULT CSceneNode::render()' just calls render in all its children. How can I force the derived classes to call CParentClass::render() instead of relying on the programmer (that's forgetful me) to do it in every derived class?

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
Why do derived classes need to render their parents? Surely the parents should render their children?


Confusion between "parent class" and "parent node".

I think his class is currently like this:


class Base {
virtual void render() { /* render children */ }
};

class Derived : public Base {
virtual void render() { Base::render(); /* Derived specific rendering */ }
};





Quote:

How can I force the derived classes to call CParentClass::render() instead of relying on the programmer (that's forgetful me) to do it in every derived class?


One easy way to do what you want is this:

class Base {
/* non-virtual */
void render() {
/* render children */
doRender();
}
protected:
virtual void doRender() = 0;
};

class Derived : public Base {
virtual void doRender() { /* Derived specific rendering */ }
};



Share this post


Link to post
Share on other sites
render() is called on root node which is a CSceneNode. CSceneNode::render is a virtual function which does nothing except call render on all it's children. If I have a class CMeshNode which is derived from CSceneNode somewhere in the graph, I have to explicitly call CSceneNode::render() in CMeshNode::render() in order to keep the recursion going. I don't like that because I or someone else will forget and screw up the recursion.

Share this post


Link to post
Share on other sites
Quote:
Original post by flobadob
rip-off, sorry I can't see how that helps. Where is the looping over children in your example classes?


In the comments [grin], It is only pseudo code.

The idea is that you no longer call a virtual method. You call a regular method, which does the recursion. That regular method then calls the virtual method that draws your derived implementation, like drawing a mesh.

With more code:

class Node {
/* non-virtual */
void render() {
std::for_each(children.begin(), children.end(), std::mem_fun(&Node::render) );

// call derived classes render function
doRender();
}
protected:
virtual void doRender() = 0;
private:
std::vector<Node*> children;
};

class Mesh : public Node {
virtual void doRender() { /* draw a mesh */ }
};

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