c ++ static_cast和引用

时间:2013-10-30 13:03:13

标签: c++ static-cast

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}}地区。我如何处理这种情况,我需要投射参考,并确保我真正得到正确的参考。

4 个答案:

答案 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_downcastdoc)的原因之一 - 在调试中它使用dynamic_cast后跟断言,在发布中它是static_cast,所以没有表现很受欢迎。

答案 3 :(得分:1)

  

(* 2)编译好,但为什么?

一般情况下,您无法静态检查动态类型;并且static_cast不进行任何动态类型检查。它允许根据静态类型进行可能有效的任何转换,包括根据动态类型无效的转换。

  

如果我将a_ref转换为B&amp;然后尝试访问属性?

未定义的行为。如果您使用static_cast,则有责任确保转换有效。

  

我如何处理需要投射参考资料的情况,并确保我真正得到正确的参考资料。

对于多态类型,请使用dynamic_cast。应用于引用,如果转换无效,它将抛出std::bad_cast

对于非多态类型,您可以自己动手。