C++ type casting int * to class
Possible Duplicate:
Regular cast vs. static_cast vs. dynamic_cast
Undefined, unspecified and implementation-defined behavior
号
我面临一个奇怪的问题。在下面的代码片段中,我定义了一个类
1 2 3 4 5 6 7 8 | class NewClass { public: void Test() { cout<<"NewClass Test"<<endl; } }; |
在我的main()方法中,我写到:
1 2 3 4 5 6 | void main() { int *ptr = new int(); NewClass *n = ((NewClass *)ptr); n->Test(); } |
号
显示"NewClass测试"。我不理解如何将任何指针类型转换为newclass,并使其仍然工作。
事先谢谢!
这是工作中的静态调度。在这种情况下,
强制转换为
结果是未定义的,但是在大多数情况下,您应该预料到不良的副作用,并且应该避免以任何代价重新解释数据。
在这种情况下,编译器可能会插入结果,因为它知道它们。此外,在这种情况下,由于没有实际依赖对象的地址或状态,因此没有显示错误:
如果您要将
如果危险不明显:这是一个极其危险的转换——所有由
在你开始思考一个复杂的为什么它不应该起作用之前,考虑一个简单的场景来帮助你尝试和想象它。
类是一个附加了方法的数据结构。当然,编译器是不同的,所以行为可以被认为是未定义的,但暂时忽略这一点。
您有一个空的数据结构(即没有数据),但仍然有一个附加到它的方法-test()。
因此,当您声明指向某个对象的指针(您关心的int)时,该指针只指向一些内存。现在您有了一个新的int(),因为ptr指向的内存大小是整数。
由于您的类没有数据,而且它也没有内部结构,这就要求内存中的对象以特定的方式(例如虚拟方法)在内存中布局,因此您可以考虑指向任何对象或实际上没有对象,因此可以调用您的方法。
创建一个这样的类,看看会发生什么:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class NewClass { private int i; public: void Test() { cout<<"NewClass Test i="<< i << endl; } }; void main() { int *ptr = new int(); *ptr = 10; NewClass *n = ((NewClass *)ptr); n->Test(); } |
看看它能打印出什么。
如果你理解了这一点,试着读读你的编译器,了解它是如何布置对象的。这将告诉您许多关于平台上存在此行为的原因。
您的方法未声明为虚方法。这意味着对它的调用完全由编译器解决,就像它是一个非方法函数一样,只是您必须在一个正式的
编译器可能会使用虚拟方法表来调度对虚拟方法的调用,如果该方法是虚拟的,那么最终可能会以垃圾代替VMT,然后开始崩溃。
也就是说,行为是未定义的,意味着任何事情都可能发生。
这似乎是未定义的行为。但是,您可以总是使用EDCOX1 17来做这件事,在C++中滥用RealTytCube运算符可以很容易地不安全。除非所需的转换本质上是低级的,否则您应该使用其他转换运算符之一。reinterpret_cast运算符可用于char*到int*等转换,或用于一个_class*到不相关的_class*的转换,这些转换本质上是不安全的。