【发布时间】:2017-10-19 12:49:34
【问题描述】:
想象一下这段代码:
class Base {
public:
virtual void foo(){}
};
class Derived: public Base {
public:
int i;
void foo() override {}
void do_derived() {
std::cout << i;
}
};
int main(){
Base *ptr = new Base;
Derived * static_ptr = static_cast<Derived*>(ptr);
static_ptr->i = 10; // Why does this work?
static_ptr->foo(); // Why does this work?
return 0;
}
为什么我在控制台上得到结果 10?我想知道,因为我认为 ptr 是指向基础对象的指针。因此该对象不包含 int i 或方法do_derived()。是否会自动生成新的派生对象?
当我也在 Base 类中声明了一个虚拟的do_derived() 方法时,选择了这个,但是为什么呢?
【问题讨论】:
-
它不起作用。这是未定义的行为。
-
未定义的行为有时可能似乎起作用,但这只是一种诱使您陷入虚假安全感的策略。它正在等待时机,并将在最糟糕的时刻开始持续且可重复地失败。
-
@πάνταῥεῖ 我认为他实际上是 不幸 :) 这种无声错误(或 UB)可能很难调试。
-
@Useless 你的意思是“不一致且不可重现在最糟糕的时刻失败”
-
@mcAngular2 区分编译的代码和正确的代码非常重要。编译的代码不一定正确。 c++ 标准指定了许多编译器不需要检测的限制,例如您对
static_cast的使用。见this link。