Re: [GD-General] Multiple Inheritance and RTTI
Brought to you by:
vexxed72
From: Thatcher U. <tu...@tu...> - 2003-02-04 18:40:57
|
On Feb 04, 2003 at 10:42 -0000, Oscar Cooper wrote: > > On the plus side, this is simple and bug-free. However, I've received very > mixed messages about the virtues and vices of dynamic_cast. Some people say > it bloats code, others say it's lean and mean. Some say it's lightning fast, > others that it's appallingly slow. I've never used it heavily enough to > notice a hit. It's slow if you use it too much; we've seen some horrible dynamic_cast<> spikes in VTune. > The next most simple approach seems to be for the Entity base class to > provide a virtual accessor function for each interface, which returns NULL > by default but can be overriden by a derived class: > > IRenderable* const renderable = entity->GetIRenderable(); > > if (renderable != 0) > renderable->Render(); > > One major drawback here seems to be that the vtable for each Entity class > will be bloated by over a hundred bytes, which seems like a bad move for > cache limited situations. My personal recommendation is to use a combination of this, and dynamic_cast<>. Use dynamic_cast<> for the rarer situations, and use GetInterfaceX() for the cases where you want to call it frequently. This should require fewer interfaces than the full number of interfaces in your code, so less vtable bloat. Although I concur with most of the other comments in the thread -- any of these approaches should work, and I don't think there's any super-nice one you left out. Re combining approaches, you could cook up some template trickery to avoid exposing the optimization to the client code: ---- // In the Entity header: class DerivedClass; // forward opaque decl class Entity { public: virtual DerivedClass* GetDerivedClass(); }; template<class T> T DynamicCastFast(Entity* e) { return dynamic_cast<T>(e); } // Here's a specialization, to avoid dynamic_cast when we're casting // to DerivedClass*. template<DerivedClass*> DerivedClass* DynamicCastFast(Entity* e) { return e->GetDerivedClass(); } // Off in its own header... class DerivedClass : virtual public Entity { DerivedClass* GetDerivedClass() { return this; } }; // Client code does this, and doesn't have to care whether the // shortcut is implemented or not: { DerivedClass* dc = DynamicCastFast<DerivedClass*>(entity); } -- Thatcher Ulrich http://tulrich.com |