考虑以下定义:
struct A {
// ...
};
struct B : public A {}; // empty
void f(B& b) { /* use b */}
void g(A& a) {
f(static_cast<B&>(a)); // is this a safe downcast?
}
int main() {
A a;
g(a);
}
在上面的示例中,a
实际上是A
的实例。
由于B
有一个空的定义,我想知道在这个特定的情况下,对f及其执行的调用是否是未定义的行为。
答案 0 :(得分:6)
不,这不是合法演员,因为它是在不属于B
类型的对象上执行的。您的程序有不确定的行为。
根据C ++ 11标准的第5.2.9 / 2段:
类型为“ cv1
B
的左值”,其中B
是类类型,可以强制转换为“引用cv2D
”其中D
是一个类 从B
派生(第10条),如果存在从“指向D
”的指针到“指向B
的指针”的有效标准转换(4.10), cv2 与 cv1 具有相同的cv资格,或更高的cv资格,B
既不是虚拟基类D
的范围,也不是D
的虚拟基类的基类。结果的类型为“ cv2D
。”xvalue类型为“ cv1B
” 可以强制转换为“对 cv2D
的rvalue引用”,其约束条件与“ cv1B
”类型的左值相同。 如果类型为“cv1B
”的对象实际上是类型为D
的对象的子对象,则结果是指封闭的D
类型的对象。否则,行为未定义
答案 1 :(得分:2)
没有。无论 safe 的含义如何,该转换都不正确,真实对象的类型为A
,而不是B
,因此您无法向下转换为B
。