c++多重继承强制转换是如何工作的

how does c++ multiple inheritance casting work?

本文关键字:工作 何工作 多重继承 转换 c++      更新时间:2023-10-16

这个问题帮助我理解了一些,但我的问题与他们的略有不同。

我在c++中理解的基本类型转换包括将内存中的一个结构重新解释为一个不同的结构。例如:

class Building{int sqFootage;};
class Office : public Building{int cubicles;};
int main(int argc, char** argv){
Office *foo = new Office();
/*The cubicles member appears after the sqFootage member on an Office,
* so the foo pointer is really just a Building* with some extra
* information after it.
*/
Building *bar = (Building*)foo;
return 0;
};

这里的关键点是,在不改变结构的情况下,办公室在记忆中可以被解释为一座建筑。这在多重继承的情况下会崩溃:

class Animal{bool alive;};
class WaterDweller : public Animal{float swimSpeed;};
class LandDweller : public Animal{float runSpeed;};
class Amphibian : public WaterDweller, public LandDweller{float transitionSpeed};
int main(int argc, char** argv){
Amphibian *amph = new Amphibian();
LandDweller *land = (LandDweller*)amph;
WaterDweller *sea = (WaterDweller*)amph;
}

在不重新组织存储器中的Amphibian结构的情况下,不可能将amph解释为LandDwellerWaterDweller假设这些模型有任何有用的意义,它们是如何工作的如果不是,这里的static_castdynamic_castreinterpret_cast是否合适?

编辑:非常感谢你的回答Sneftel。你在一条评论中提供的TinyDr链接非常有用,我会牢记避免c型石膏的建议。

对于那些好奇的人来说,以下是我尝试运行以下代码时得到的提示:

land 0x22c8018
sea 0x22c8010
run 0x22c801c
swim 0x22c8014
land alive 0x22c8018
sea alive 0x22c8010

你可以在这里看到,即使土地和水上居民继承了同一个基本阶级,他们也包括自己的副本,就好像基本阶级不同一样。这就引出了Sneftel在评论中提到的钻石问题。

如果查看存储在land中的地址,您会注意到它是一个比amph更高的数字。这是因为,在C++中,强制转换最终可能会将指针运算作为其内部操作的一部分。Amphibian中有一个WaterDweller,以及之后的LandDweller。当强制转换到数据不从派生类的开头开始的基类型时,指针会调整到该基类数据的开头。

顺便说一句,听从Dieter的建议,不要在C++中使用C风格的强制转换(尤其是指针类型)。C++中C风格转换的行为是static_castreinterpret_castconst_cast的混合体,并且很容易在没有编译器警告的情况下完成与预期不同的操作。最好让你正在做的选角类型明确。