这种向下转换会导致未定义的行为吗?
Does this downcasting lead to undefined behavior?
鉴于此示例:
class Base
{
public:
void foo() {};
};
class Derived : public Base
{
};
int main()
{
Base b;
Derived* d = static_cast<Derived*>(&b);
d->foo();
}
我只有三种情况:当void foo()
:
- 是
Base
、 的成员
- 并且当它是
Derived
、 的成员时
- 并且当它是
Base
和 Derived
的成员时。
我的问题是:
成员访问表达式d->foo()
是否在所有三种情况下都是未定义的行为?
如果成员访问表达式是 UB,唯一的解决方法是使用 dynamic_cast
?
来自the C++ standard §7.6.1.9.11
A prvalue of type “pointer to cv1 B
”, where B
is a class type, can be converted to a prvalue of type “pointer to cv2 D
”, where D
is a complete class derived from B
,
...
If the prvalue of type “pointer to cv1 B
” points to a B
that is actually a base class subobject of an object of type D
, the resulting pointer points to the enclosing object of type D
.
Otherwise, the behavior is undefined.
所以使用 static_cast
进行向下转换只有在您知道(通过其他方式)转换有效时才有效。如果您使用 不是 的 Base
和 Derived
并使用 static_cast
假装它是,则您调用了未定义的行为,甚至在您尝试取消引用指针之前。因此,您可以删除 d->foo()
行,并且 still 具有未定义的行为。是演员阵容不好
如果您的目标是有条件地检查您是否拥有子类的实例,那么您需要 dynamic_cast
.
鉴于此示例:
class Base
{
public:
void foo() {};
};
class Derived : public Base
{
};
int main()
{
Base b;
Derived* d = static_cast<Derived*>(&b);
d->foo();
}
我只有三种情况:当void foo()
:
- 是
Base
、 的成员
- 并且当它是
Derived
、 的成员时
- 并且当它是
Base
和Derived
的成员时。
我的问题是:
成员访问表达式
d->foo()
是否在所有三种情况下都是未定义的行为?如果成员访问表达式是 UB,唯一的解决方法是使用
dynamic_cast
?
来自the C++ standard §7.6.1.9.11
A prvalue of type “pointer to cv1
B
”, whereB
is a class type, can be converted to a prvalue of type “pointer to cv2D
”, whereD
is a complete class derived fromB
,...
If the prvalue of type “pointer to cv1
B
” points to aB
that is actually a base class subobject of an object of typeD
, the resulting pointer points to the enclosing object of typeD
. Otherwise, the behavior is undefined.
所以使用 static_cast
进行向下转换只有在您知道(通过其他方式)转换有效时才有效。如果您使用 不是 的 Base
和 Derived
并使用 static_cast
假装它是,则您调用了未定义的行为,甚至在您尝试取消引用指针之前。因此,您可以删除 d->foo()
行,并且 still 具有未定义的行为。是演员阵容不好
如果您的目标是有条件地检查您是否拥有子类的实例,那么您需要 dynamic_cast
.