【发布时间】:2019-02-13 07:07:51
【问题描述】:
class Parent
{};
class A_child : public Parent
{
void A_method();
};
class B_child : public Parent
{
void B_method();
};
void main()
{
A_child a;
Parent *p = &a;
B_child *b = (B_child*)&p;
b->B_method();
}
这段代码是用 C++ 编写的。这是一个逻辑错误,因为我们试图将“猫”变成“狗”。但它有效。谁能解释为什么以及如何?
【问题讨论】:
-
这是未定义的行为。它不工作,它只是不会崩溃。
-
在
B_child中添加一个int,将其设置为B_method中的某个值,然后看看效果如何。 -
@tkausl - 我不明白。你的意思是说这段代码行不通?
-
(B_child*)是 C 风格的演员表。是神锤。使用 C 型铸件,您可以将圆形钉子强制插入方孔。无论想法多么糟糕,它都会使 A 适合 B。避免 C 风格的强制转换。在此处使用dynamic_cast并注意返回的空指针。 -
一切都与记忆有关。
A_child和B_child具有相同的结构,因此适合内存中的相同模式。通过使用 C 风格的类,您只是将b指向a的内存地址(通过p)。因为记忆模式是相同的,所以它是偶然的。但是,正如其他人指出的那样,如果尽管从相同的基类继承,但结构不同的类,它们在内存中的布局会有所不同,并且 C 风格的强制转换将是未定义的行为。 @zzxyz 建议添加一个int来“扰乱”b的内存模式并导致失败。