Hi I\'ve started working on some pre-existing code which consists of a tree of elements, each element is a descendant of a generic element which has a type data member.
dynamic_cast
is not that slow, and you're likely not going to be able to do better. Profile and prove that it is a performance bottleneck before looking at alternative solutions. Never ever do anything because you maybe heard somewhere that it might be slow.
Let the base class in the tree structure have a pure virtual Visit() method.
class CBase {
virtual void Visit(CVisitor* visitor) const = 0;
};
Let the inherited classes implement it:
class CFoo : public CBase {
virtual void Visit(CVisitor* visitor) const {
visitor->Accept(this);
}
};
class CBar : public CBase {
virtual void Visit(CVisitor* visitor) const {
visitor->Accept(this);
}
};
The final magic:
class CVisitor {
void Accept(CFoo* foo) {
// operate on CFoo*
}
void Accept(CBar* bar) {
// operate on CBar*
}
};
So all you need to do is to create Accept and Visit methods for new types and traverse the tree with the CVisitor class and then you can operate on any type in the tree without any pointer casts.
Hope this helps.
Cheers
If dynamic_cast/RTTI is not an option, an easy way of dealing with this type of situation is by use of the Visitor Pattern
Basically, you define a base class that defines methods that do the casting for you safely:
// Forward declarations.
class CFoo;
class CBar;
class CommonBase
{
public:
virtual CFoo* GetFoo( void ) { return NULL };
virtual CBar* GetBar( void ) { return NULL };
};
class CFoo : public GenericBase, public CommonBase
{
.
.
public:
CFoo* GetFoo( void ) { return this };
};
class CBar : public GenericBase, public CommonBase
{
.
.
public:
CBar * GetBar( void ) { return this };
};
Now, given a pointer to a CommonBase object one can downcast by "visting":
CommonBase *p;
CFoo pFoo = p->GetFoo();
if( pFoo )
{
// Winner!
}