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
505 views
in Technique[技术] by (71.8m points)

casting - C++ cannot convert from base A to derived type B via virtual base A

I have three classes:

class A {};

class B : virtual public A {};
class C : virtual public A {};

class D: public B, public C {};

Attempting a static cast from A* to B* I get the below error:

cannot convert from base A to derived type B via virtual base A
See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

In order to understand the cast system, you need to dive into the object model.

The classic representation of a simple hierarchy model is containment: if B derives from A then the B object will, in fact, contain an A subobject alongside its own attributes.

With this model downcasting is a simple pointer manipulation by an offset known at compilation time, which depends on the memory layout of B.

This is what static_cast does: a static cast is dubbed static because the computation of what is necessary for the cast is done at compile-time, be it pointer arithmetic or conversions (*).

However, when virtual inheritance kicks in, things tend to become a bit more difficult. The main issue is that with virtual inheritance all subclasses share the same instance of the subobject. In order to do that, B will have a pointer to an A, instead of an A proper, and the A base class object will be instantiated outside of B.

Therefore, it's impossible at compilation time to be able to deduce the necessary pointer arithmetic: it depends on the runtime type of the object.

Whenever there is a runtime type dependency, you need RTTI (RunTime Type Information), and making use of RTTI for casts is the job of dynamic_cast.

In summary:

  • compile-time downcast: static_cast
  • run-time downcast: dynamic_cast

The other two are also compile-time casts, but they are so specific that it's easy to remember what they are for... and they are smelly, so better not use them at all anyway.

(*) As noted by @curiousguy in the comments, this only holds for downcasting. A static_cast allows upcasting regardless of virtual or simple inheritance, though then the cast is also unnecessary.


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

...