13
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) produces an error and i understand why. (*2) compiles fine, but why? And, as long as it compiles and suppose B contains some attributes, what if i cast a_ref to B& and then try to access the attributes? I think i will have an run-time error or something.

So, as i can see, there is a situation which leads to crash and there are no ways to avoid it, unlike with dynamic_cast where one can check the result of casting for null or put code in a try-catch region. How do i have to deal with such situation where i need to cast references and be sure that i really get the right references.

4

4 回答 4

9

来自标准 n3337 草案 5.2.9/2

“cv1 B”类型的左值,其中 B 是类类型,如果从“指向D”到“指向 B”的指针存在 (4.10),cv2 与 cv1 具有相同的 cv 限定或大于 cv1 的 cv 限定,并且 B 既不是 D 的虚拟基类也不是虚拟基类的基类的 D。

在你的情况下:

B是从 派生的类A,两者都是非常量,并且允许从A*to转换,不是 的虚拟基类。B*AD

于 2013-10-30T13:05:27.647 回答
5

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

情况 1 类型不直接兼容,因为没有操作符来描述 A 和 B 之间的复制关系

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

于 2013-10-30T13:07:52.960 回答
4

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

于 2013-10-30T13:08:10.323 回答
1

(*2) 编译得很好,但是为什么呢?

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

如果我将 a_ref 转换为 B& 然后尝试访问属性怎么办?

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

我必须如何处理这种情况,我需要进行引用并确保我真的得到了正确的引用。

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

对于非多态类型,你自己做。

于 2013-10-30T13:16:02.910 回答