Virtual inheritance and dynamic_cast
| Tue, 2004-06-08 16:07 | |
|
Hi guys Before we start - appologies for a rather verbose posting... ![]() I wonder if anyone can suggest some workaround or magic to overcome the following.I have several mixin (M) classes since I want to have some abstract APIs. For some M classes I wish to provide a corresponding C class which supplies a default implementation for the interface. I have a chain of maybe 3 or 4 classes which inherit from M and C classes above them, as follows (excuse the hideous ASCII art hopefully you can see what I mean)MClass1 <----virtual------CClass1 MClass2 <----virtual------CClass2 MClass3 <----virtual------CClass3<-----------CMyClass MClass2 virtually inherits from MClass1 MClass3 virtually inherits from MClass2 CClass2 virtually inherits from CClass1 CClass3 virtually inherits from CClass2 I couldn't show these "vertical" inheritances well on the diagram since the spacing screwed up badly! I have to use virtual inheritance otherwise the methods in the classes are not resolved correctly. It is extremely useful for me to have the intermediate classes CClass1, 2, and 3 since these provide 90% functionality that does not need to be overridden by CMyClass. Besides, if I don't do this, then all the M class methods have to be implemented in every CMyClass implementation, massively bloating the end class and resulting in lots of unmaintainable duplication. Now, if I have a CMyClass, I can cast down to MClass1, but from an MClass1 I cannot get back to CMyClass - well, I could if dynamic_cast were available! Since virtual inheritance is used, the compiler can't figure out the hierarchy if I try to static_cast, and using C style pointer casting I think is asking for trouble... Anyone got any suggestions on how to overcome this problem in the Symbian environment and still be able to use the abstract base classes to specify interfaces? Paul |
|







Forum posts: 683
What about having a virtual ClassID method, that would return the ID of the class? Each concrete class implements this. The place to declare it would be at the MClass1, since all inherit from it.
Then get the class id by calling the method, and type cast to the proper subtype?
Forum posts: 21
Thanks for the response. Actually I do have a kind of "id" method in the base class, and I know exactly which kind of object I'd like to get.
The problem is that I only want to work in terms of M classes, and I only maintain pointers to MClass1 instances since I keep all such objects (eg of class CMyClass) in an RPointerArray< MClass1 >.
Given a pointer to a base class of MClass1,
MClass1* mclass1instance = (some valid address);
MClass3* therightobject = dynamic_cast< mclass1instance);
Of course, dynamic_cast is not available in Symbian.
static_cast won't compile either,
and doing C style casting
MClass3* therightobject = ( MClass3* ) ( ( void* ) mclass1instance );
I think that this doesn't in fact return the correct address.
So am I stuffed, or do I need to recode everything in terms of just C classes, and completely lose the abstract M class API's?
This is pissing me off!
Paul
Addicted to phones
Forum posts: 21
see http://www.symbian.com/developer/techlib/v70docs/SDL_v7.0/doc_source/DevGuides/EssentialIdioms/MultipleInheritance.guide.html
Forum posts: 21
Actually you can do multiple inheritance, it just isn't recommended by Symbian since it might confuse their poor developers, LOL.
Paul
Addicted to phones
Forum posts: 363
I had a similar problem a couple years back and if I recall correctly, there are no "neat" solutions. Either you will have a method in your M-classes that returns a pointer to a base class (CBase*) and then implement the casts with templates or macros, or you have to redesign your hierarchy.
What comes to multiple inheritance, the compilers do support it, but it is not recommended in Symbian because some parts of the system code assume fixed offsets for CBase-derived class member variables, and this can lead to unexpected crashes when MI is used.
Cheers,
Pawel