conv.h
class Base
{
public:
void foo();
};
class Derived: public Base
{
public:
void bar();
};
class A {};
class B
{
public:
void koko();
};
conv.cpp
void Base::foo()
{
cout<<"stamm";
}
void Derived::bar()
{
cout<<"bar shoudn't work"<<endl;
}
void B::koko()
{
cout<<"koko shoudn't work"<<endl;
}
的main.cpp
#include "conv.h"
#include <iostream>
int main()
{
Base * a = new Base;
Derived * b = static_cast<Derived*>(a);
b->bar();
Derived * c = reinterpret_cast<Derived*>(a);
c->bar();
A* s1 = new A;
B* s2 = reinterpret_cast<B*>(s1);
s2->koko();
}
输出:
bar shoudn't work
bar shoudn't work
koko shoudn't work
为什么方法栏在运行时被成功调用,尽管我创建了一个未派生的Base类?它甚至可以用于两种类型的转换(静态和重新解释转换)。
与上述问题相同,但与不相关的类别(A&amp; B)??
答案 0 :(得分:6)
未定义的行为可以执行任何操作,包括似乎可以正常工作。
答案 1 :(得分:1)
它正在工作(读:“编译而不是崩溃”)'因为你从不在名义上的“成员”函数中使用this
指针。例如,如果你试图打印出一个成员变量,你就会得到你想要的垃圾输出或崩溃 - 但是这些函数现在并不依赖于它们应该属于的类中的任何东西。对于他们所关心的所有人来说,this
甚至可以NULL
。
答案 2 :(得分:0)
编译器知道Derived
可以使用成员函数foo()
和bar()
并知道在哪里找到它们。在你完成“技巧”后,你有指向Derived
的指针。
它们是Derived
类型的指针 - 无论数据与这些指针相关联 - 都允许它们调用函数foo()
和{{ 1}}与Derived相关联。
正如已经提到的,如果您实际使用了指针处的数据(即读取或写入了属于Derived类的kook()
的数据成员(在这种情况下您没有),本来就是访问不属于你对象的内存。