c++ static_cast and references

c++ static_cast and references

本文关键字:and references cast static c++      更新时间:2023-10-16
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 转换结果或将代码放在try-catch区域中。我必须如何处理需要投射引用并确保我真的得到正确的引用的情况。

来自标准 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 的虚基类。

static_cast<>只会检查类型是否兼容

在 1 类型不直接兼容的情况下,因为 re 不是描述 A 和 B 之间复制关系的运算符

在情况 2 中,强制转换是引用强制转换,就编译器而言A*可以转换为B*,因为它们是兼容的。编译器将不知道指针a_ref包含什么,因此这就是它允许您使用它的原因。 dynamic_cast<>还会检查指针指向的类。

这是我使用

boost::polymorphic_downcast (doc) 的原因之一 - 在调试中它使用 dynamic_cast 后跟断言,在发布中它是 static_cast ,所以没有性能影响。

(*2) 编译正常,但为什么呢?

通常,您不能静态检查动态类型;static_cast 不会执行任何动态类型检查。它允许根据静态类型可能有效的任何转换,包括根据动态类型无效的转换。

如果我将a_ref投射到 B& 然后尝试访问属性怎么办?

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

必须如何处理需要投射引用并确保我真的得到正确的引用的情况。

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

对于非多态类型,您只能靠自己。