【发布时间】:2020-08-16 06:09:22
【问题描述】:
#include <iostream>
struct X
{
virtual void x() = 0;
};
struct Y
{
virtual void y() = 0;
};
struct XY : X, Y
{
void x() override { std::cout << "X\n"; }
void y() override { std::cout << "Y\n"; }
};
int main()
{
XY xy;
X* xptr = &xy;
Y* yptr = (Y*)xptr;
yptr->y(); //prints "X"....
((Y*)((X*)(&xy)))->y(); // prints "Y"....
}
输出:
X
Y
有人能详细解释一下为什么会这样吗?为什么第一个调用打印 X 以及为什么两个调用彼此不同?
【问题讨论】:
-
Y* yptr = (Y*)xptr;这个演员表实际上是在做一个reinterprest_cast,它只是强制转换。这不合法,也不安全。事实上,这是未定义的行为。您可以安全地将xy隐式转换为yptr。 -
对我来说似乎是未定义的 bahviour。您在不相关的类型之间进行转换。如果您使用 dynamic_cast,它可能会起作用?
-
在
reinterpret_cast之后,你仍在调用指向X的指针,因此它调用了X的函数。即使是 UB 也没什么好奇怪的 -
@user,不,这是不正确的。它将 X 的 vtable 解释为好像它是 Y vtable。碰巧它们是“兼容的”,因为它们具有相同数量的具有相同签名的函数。
-
这说明了为什么你不应该 C 风格强制转换为指针或引用。
标签: c++ casting multiple-inheritance virtual-functions