I'm currently working on integrating a third-party package that uses lots of RTTI stuff on a non-RTTI platform (Android). Basically, I did my own RTTI implementation but I'm stuck on a problem.
The issue is that a lot of classes are having the diamond inheritance problem since all the classes derive from the same base class (object).. and so, if I want to downcast from the base class to the derived class, I have to use a dynamic_cast - but RTTI is not available! How do I convert an object from parent to child when there are virtual inheritance without dynamic_cast?
It looks like that:
class A
{
public:
virtual char* func() { return "A"; };
};
class B : public virtual A
{
public:
//virtual char* func() { return "B"; };
};
class C : public virtual A
{
public:
//virtual char* func() { return "C"; };
};
class D : public B, public C
{
public:
//virtual char* func() { return "D"; };
};
D d;
A* pa = static_cast<A*>(&d);
D* pd = static_cast<D*>(pa); // can't do that! dynamic_cast does work though...
Those are my errors:
error C2635: cannot convert a 'A*' to a 'D*'; conversion from a virtual base class is implied
error C2440: 'initializing' : cannot convert from 'test_convert::A *' to 'test_convert::D *' Cast from base to derived requires dynamic_cast or static_cast
Any ideas?
The fact, that the cast is safe is known by the compiler at compile time. This means, that dynamic_cast does not need to use RTTI. We can say in general, that dynamic_cast is a tool for moving around the inheritance tree – up and down.
The Diamond Problem is fixed using virtual inheritance, in which the virtual keyword is used when parent classes inherit from a shared grandparent class. By doing so, only one copy of the grandparent class is made, and the object construction of the grandparent class is done by the child class.
Solution of the Diamond Problem: The solution is to use of the keyword virtual on the two parent classes ClassA and ClassB. Two-parent classes with a common base class will now inherit the base class virtually and avoid the occurrence of copies of the base class in the child class (ClassC here).
The answer to the titular question is no.
You can only do this cast with dynamic_cast
; no other cast will do this.
If you can't design your interfaces so that you don't need to perform this type of cast then the only thing you can do is make the casting functionality part of your class hierarchy.
E.g. (horribly hacky)
class D;
class A
{
public:
virtual D* GetDPtr() { return 0; }
};
class B : public virtual A
{
};
class C : public virtual A
{
};
class D : public B, public C
{
public:
virtual D* GetDPtr() { return this; }
};
Android does support RTTI. You need latest NDK (at least r5, latest is r6) and you need to compile against the GNU stdlibc++ instead of the default.
Even before, there was the CrystaX's rebuild which did support exceptions and rtti (we had to use that until official NDK r5c because r5a and r5b had the support, but crashed on older (pre-2.3) systems).
PS: Somebody should really forbid vendors say they support C++ when they don't support exceptions and rtti, because most of standard library, and that's part of the C++ standard, does not work without either. Plus not supporting them is silly, especially for the exceptions, because code with exceptions is more efficient than one without (provided they are properly used to signal exceptional cases).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With