我正在阅读 this 不幸的是不明白为什么编译器不允许从 Derived** 转换为 Base**.我也看到了 this 没有给出比 parashift.com 的链接更多的信息.
I was reading this and unfortunately could not understand in depth why the compiler does not allow conversion from Derived** to Base**. Also I have seen this which gives no more info than the parashift.com's link.
让我们一行一行地分析这段代码:
Let us analyze this code line by line:
Car car;
Car* carPtr = &car;
Car** carPtrPtr = &carPtr;
//MyComment: Until now there is no problem!
Vehicle** vehiclePtrPtr = carPtrPtr; // This is an error in C++
//MyComment: Here compiler gives me an error! And I try to understand why.
//MyComment: Let us consider that it was allowed. So what?? Let's go ahead!
NuclearSubmarine sub;
NuclearSubmarine* subPtr = ⊂
//MyComment: this two line are OK too!
*vehiclePtrPtr = subPtr;
//MyComment: the important part comes here... *vehiclePtrPtr is a pointer to
//MyComment: a vehicle, particularly in our case it points to a Car object.
//MyComment: Now when I assign to the pointer to the Car object *vehiclePtrPtr,
//MyComment: a pointer to NuclearSubmarine, then it should just point to the
//MyComment: NuclearSubmarine object as it is indeed a pointer to a Vehicle,
//MyComment: isn't it? Where is my fault? Where I am wrong?
// This last line would have caused carPtr to point to sub!
carPtr->openGasCap(); // This might call fireNuclearMissle()!
这与一碗香蕉不是一碗水果的原因基本相同.如果一碗香蕉是一碗水果,你可以把一个苹果放进碗里,它就不再是一碗香蕉了.
It's basically the same reason why a bowl of bananas is not a bowl of fruits. If a bowl of bananas were a bowl of fruits, you could put an apple into the bowl, and it would no longer be a bowl of bananas.
只要您只检查碗,转换是无害的.但是一旦您开始修改它,转换就会变得不安全.这是要牢记的关键点.(这就是为什么不可变 Scala 集合实际上允许转换,但可变集合禁止它的确切原因.)
As long as you only inspect the bowl, the conversion is harmless. But as soon as you start modifying it, the conversion becomes unsafe. This is the key point to bear in mind. (This is the precise reason why the immutable Scala collections actually allow the conversion, but the mutable collections prohibit it.)
与您的示例相同.如果有从 Derived**
到 Base**
的转换,你可以放置一个指向苹果的指针,如果类型系统承诺只存在指向香蕉的指针.轰!
Same with your example. If there was a conversion from Derived**
to Base**
, you could put a pointer to an apple were the type system promised only a pointer to a banana could exist. Boom!
这篇关于从派生**到基础**的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!