struct A{};
struct B : A{};
int main()
{
A a;
A& a_ref = a;
static_cast<B>(a); // *1
static_cast<B&>(a_ref); // *2
return 0;
}
(* 1)产生错误,我理解为什么。 (* 2)编译好,但为什么?并且,只要它编译并假设B
包含一些属性,如果我将a_ref
转换为B&
然后尝试访问属性该怎么办?我想我会遇到运行时错误。
所以,正如我所看到的,有一种情况会导致崩溃并且没有办法避免它,与dynamic_cast
不同,其中可以检查转换为null的结果或将代码放入{ {1}}地区。我如何处理这种情况,我需要投射参考,并确保我真正得到正确的参考。
答案 0 :(得分:8)
从标准n3337草案5.2.9 / 2
类型为“cv1 B”的左值,其中B是类类型,可以转换为类型“引用cv2 D”,其中D是类 从B得出(第10条),如果存在从“指向D的指针”到“指向B的指针”的有效标准转换(4.10), cv2与cv1具有相同的cv资格,或者比cv1更高的cv资格,并且B既不是虚拟基类 D也不是D的虚基类的基类。
在你的情况下:
B
是派生自A
的类,两者都是非常量的,允许从A*
转换为B*
,A
不是虚拟基础等级D
。
答案 1 :(得分:4)
static_cast<>
只会检查类型是否兼容
如果1种类型不能直接兼容,因为re不是操作员来描述A和B之间的复制关系
在第2种情况下,强制转换是一个参考强制转换,就编译器而言A*
可以转换为B*
,因为它们是兼容的。编译器不会知道指针a_ref
的含义,因此它允许您使用它。 dynamic_cast<>
检查指针指向的类。
答案 2 :(得分:4)
这是我使用boost::polymorphic_downcast
(doc)的原因之一 - 在调试中它使用dynamic_cast
后跟断言,在发布中它是static_cast
,所以没有表现很受欢迎。
答案 3 :(得分:1)
(* 2)编译好,但为什么?
一般情况下,您无法静态检查动态类型;并且static_cast
不进行任何动态类型检查。它允许根据静态类型进行可能有效的任何转换,包括根据动态类型无效的转换。
如果我将a_ref转换为B&amp;然后尝试访问属性?
未定义的行为。如果您使用static_cast
,则有责任确保转换有效。
我如何处理需要投射参考资料的情况,并确保我真正得到正确的参考资料。
对于多态类型,请使用dynamic_cast
。应用于引用,如果转换无效,它将抛出std::bad_cast
。
对于非多态类型,您可以自己动手。