Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
627 views
in Technique[技术] by (71.8m points)

casting - C++ - downcasting a diamond shape inherited object without RTTI/dynamic_cast

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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; }
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...