c++ multiple inheritance casting

与世无争的帅哥 提交于 2019-12-03 10:27:37

If Base has virtual function (even be it virtual destructor), then:

Derived *pDerived = dynamic_cast<Derived *>(object);

Else, use

Derived *pDerived = static_cast<Derived *>(object);

Note that if Base doesn't have virtual function, then dynamic_cast will NOT compile. In dynamic_cast, only the source has to be a polymorphic object, in order to compile, and if the destination isn't polymorphic, then dynamic_cast will return null pointer:

Suppose A and B are polymorphic type, and C is non-polymorphic, then

A *pA = dynamic_cast<A*>(new C()); //error - source is not polymorphic!

A *pA = dynamic_cast<A*>(new B()); //ok
if ( pA == 0 )
      cout << "pA will be null if B is not derived from A" << endl;

C *pC = dynamic_cast<C*>(new B()); //ok
if ( pC == 0 )
       cout << "pC must be null" << endl;

If you know for sure that the object is of Derived class - use static_cast, otherwise use dynamic_cast and check the result.

You can use dynamic_cast<Derived*>(object) for that, and if the cast succeeds you'll get a Derived* returned, else the cast will return NULL. You use this type of cast if Base is a polymorphic type, ie. contains a virtual function, and if this is not the case, you can use a static_cast<Derived*> instead.

Your problem is that you have an Object class that does not inherit from your interface ITouchResponder and therefore your dynamic_cast from Object to your interface is invalid. You can only do a dynamic_cast on classes that inherit from one another, that's the whole purpose of polymorphism, so like you suggested in your example, your Object class should inherit publicly from your interface.

Essentially, you're doing an upcast here, ITouchResponder *res = dynamic_cast<ITouchResponder*>(this); from Derived to Base Interface, however your Derived doesn't really derive from your interface, so that's why it doesn't work.

There are several ways but they don't have the same impact :

Derived* derived = static_cast<Derived*>(object);

Use this one if you know at compile time that it should be of the correct type. It will not fail at runtime if it's not possible but will at compile time.

Derived* derived = dynamic_cast<Derived*>(object);

Use this if you're not sure and want the runtime to automatically check if it's possible. If it is you'll get a valid pointer, if not you'll get a nullptr. Know that dynamic_cast<> checks are costly in time performance so a lot of people sometimes use associative containers with type_info pointers as key, where possible, because the check is less costly, but really it depends on the context. To get more infos, look for the typeid keyword.

Now, there is also the C way of doing it but it's not recommanded because it's not clear what exactly will the compiler generated. At least with those previous ways you know exactly how the code should behave. So I'll not describe it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!