Re: [GD-General] Multiple Inheritance and RTTI
Brought to you by:
vexxed72
From: Noel L. <ll...@co...> - 2003-02-04 12:06:42
|
On Tue, 04 Feb 2003 10:42:59 +0000 Oscar Cooper <osc...@cr...> wrote: > I'm guessing that there will be less than a hundred derived classes, no more > than thirty two interfaces, and a few hundred object instances at any given > time. dynamic_cast is OK. It will do exactly what you want, and I don't expect it to be so slow as to be noticeable in your case. However, you will be forced to turn RTTI on for all your classes, which you might not want to do. Also RTTI code and non-RTTI code don't like to mix, so if you're using external libraries that don't have RTTI, that might just decide it for you. > Finally, the Entity base class could provide a single virtual accessor > function that takes an interface identifier as a parameter: > > IRenderable* const renderable = reinterpret_cast<IRenderable*>( > entity->QueryInterface(IID_IRenderable)); > That's a good, simple approach. It's so simple that there's no need to involve C++ RTTI. Like somebody else mentioned, I recommend you use only one function to get all your interfaces instead of one function per interface. That what I use also. That way you get no bloating of vtables and it's a cleaner interface (although you'll have to cast the returned pointer from void * to whatever you want). > There are two obvious implementations of this method: The derived class > either implements the function as conditional code, or maintains some kind > of look-up table. The former seems more favourable as a cross-platform > solution, again for cache reasons, but contains the most implementation > pitfalls. I just did it with conditional statements. They seemed to be just fine. > Any of these methods could be supplemented with an inexpensive test for > interface support by adding a constant data overhead to each Entity object > (in this case, four bytes). Each interface is assigned an identifier, which > corresponds to a single bit in a bitfield owned by the base class: That's an interesting optimization. I doubt you will need it calling it only 1000 times per frame but it's worth keeping in mind. I guess it depends whether most of your objects inherit from a lot of the interfaces or just a couple. Also, if you do that, you'll be forced to come up with some way of giving unique identifiers to each interface, which is not trivial, especially if other people are extending your code. You might have to register interfaces somehow and all that bookkeeping. > So, has anyone tried more than one of these approaches and found one to be > superior to the other(s) in production code? Are there any other ways to > achieve the same results which may be more suitable? Does anyone have any > tricks or tips they'd like to share? That's pretty much it. You've covered all the main points. I found the book Inside COM to be extremely enlightening. The author goes step by step developing a COM-like approach (until it becomes full-blown COM), which is pretty much what you want to see. You can check out one of my articles in Game Programming Gems 2. It talks about exactly this topic, and it provides some sample code (although it seems you have figured it all of it by yourself already). Finally, at the danger of blowing my own trumpet too much, I have a whole chapter dedicated to this in my upcoming book "C++ for Game Programmers" (http://www.amazon.com/exec/obidos/ASIN/1584502274) --Noel ll...@co... |