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 ++编写的。这是一个逻辑错误,因为我们试图将“猫”变成“狗”。但它的确有效。谁能解释为什么以及如何解释?
谁能解释为什么以及如何解释?
Parent
是B_child
的基地,所以从Parent *p
类型到B_child*
的转换很好。但是,仅当p
实际指向B_child
实例的基础子对象时,才会定义通过此转换指针访问指向对象的行为。
前提条件不成立,因此程序的行为未定义。可能的行为包括,但都不保证:
- working
- not working
- random output
- non-random output
- the expected output
- unexpected output
- no output
- any output
- crashing at random
- crashing always
- not crashing at all
- corruption of data
- different behaviour, when executed on another system
- , when compiled with another compiler
- , on tuesday
- , only when you are not looking
- same behaviour in any or all of the above cases
- anything else within the power of the computer (hopefully limited by the OS)
除非你能证明演员表是正确的,否则从不static_cast
,reinterpret_cast
或C风格将表达式转换为另一种类型。你可以在不确定的情况下使用dynamic_cast
。
这很可能但不能保证不会导致错误,因为你的B_method实际上是static
。
一旦该方法变为virtual
(现在需要用于访问vtable的类指针来查找函数地址),访问类数据,或者您打喷嚏或查看编译器有趣,您将处理未绑定的内存访问。
我应该强调,虽然假设编译器不需要取消引用类指针,但它是允许的,并且可能是任何特定编译器实现所要求的。
进一步阅读...查看接受的答案Difference between Object and instance : C++在访问与类的特定实例关联的instance data
之前,不太可能查看类指针。
或者......另一种方式来解决这一切。如果您可以在函数声明前面使用static
,则使用无效指针调用它可能会起作用。
也可以看看:
class MyClass
{
public:
int doSomething(int x)
{
printf("%d", x);
return x;
}
};
int main()
{
MyClass *pMyClass = nullptr;
pMyClass->doSomething(42);
}