• Advertisement
Sign in to follow this  

Virtual functions and recursion

This topic is 3756 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

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
Advertisement
Why do derived classes need to render their parents? Surely the parents should render their children?

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
rip-off, sorry I can't see how that helps. Where is the looping over children in your example classes?

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
Sign in to follow this  

  • Advertisement