考虑以下示例:
class Base {
public:
int data_;
};
class Derived : public Base {
public:
void fun() { ::std::cout << "Hi, I'm " << this << ::std::endl; }
};
int main() {
Base base;
Derived *derived = static_cast<Derived*>(&base); // Undefined behavior!
derived->fun();
return 0;
}
根据 C++ 标准,函数调用显然是未定义的行为。但在所有可用的机器和编译器(VC2005/2008,RH Linux 和 SunOS 上的 gcc)上,它按预期工作(打印“Hi!”)。有谁知道配置此代码可能无法正常工作?或者可能是具有相同想法的更复杂的示例(请注意,Derived 无论如何都不应该携带任何额外的数据)?
更新:
从标准 5.2.9/8 开始:
“指向 cv1 B 的指针”类型的右值,其中 B 是类类型,可以转换为“指向 cv2 D 的指针”类型的右值,其中 D 是从 B 派生的类(第 10 条),如果一个有效的标准存在从“指向 D 的指针”到“指向 B 的指针”的转换 (4.10),cv2 的 cvqualification 与 cv1 相同或更高,并且 B 不是 D 的虚拟基类。空指针值 (4.10)转换为目标类型的空指针值。如果“指向 cv1 B 的指针”类型的右值指向实际上是 D 类型对象的子对象的 B,则生成的指针指向 D 类型的封闭对象。否则,强制转换的结果是未定义的。
还有一个 9.3.1(感谢@Agent_L):
如果为非 X 类型或从 X 派生的类型的对象调用类 X 的非静态成员函数,则行为未定义。
谢谢,迈克。