【问题标题】:C++ proper way to static_castC++ 正确的 static_cast 方法
【发布时间】:2013-04-22 12:20:55
【问题描述】:

static_cast不会抛出异常。但如果不成功,就会产生未定义的结果。检查演员表是否成功的最正确方法是什么?

这会有帮助吗?

NewType new_typ_obj = static_cast<NewType>(obj); 

if (new_typ_obj)
    new_typ_obj.do();

【问题讨论】:

  • 正确的静态转换方式是不要(完全转换)。

标签: c++ exception casting static-cast


【解决方案1】:

static_cast 不会为您提供有关成功的信息。如果您需要进行动态类型转换,请使用 dynamic_cast 或 boost any 之类的库。

【讨论】:

    【解决方案2】:

    在您给出的示例中,static_cast可能根据所涉及的类型抛出异常,例如,如果 NewType 的构造函数抛出异常。如果不存在从objNewType 类型的任何转换链,那么它甚至不会编译。

    您可能正在考虑使用static_cast 将指向基址的指针转换为指向派生的指针,这是dynamic_cast 检查的情况。在这种情况下,无法判断static_cast 是否成功。作为程序员,您有责任仅在正确的情况下使用它。

    【讨论】:

      【解决方案3】:

      static_cast 仅在您在指针、引用或指向成员类型的指针之间进行强制转换时具有未定义的行为。当您执行向下转换为不是真正指向的对象类型的类型时,就会发生这种情况。

      在您的示例中,除非 NewType 是指针或引用类型的 typedef 并且 obj 也是这些类型,否则如果强制转换无效,编译器会给您一个错误。

      执行if (new_typ_obj) 对检查任何static_cast 情况下的转换是否成功没有意义。如果NewType 不是这些多态类型之一,那么使用new_type_obj 作为条件只有在您有某种方法将其转换为bool(或者它 bool)时才有效。即便如此,也与演员无关。相反,如果您通过指向继承层次结构的指针static_casting,那么static_cast 将不会为您提供有关它是否成功的任何信息。为此,您需要dynamic_cast

      【讨论】:

        【解决方案4】:

        static_cast 如果您要转换的类型不相关与您要转换的类型,则不会编译。除了与所有类型相关的void *。因此 static_cast 在编译时仍然是一个很好的保证。

        仍然存在做错事的危险。

        我的个人规则是:

        • 更喜欢使用 static_cast 进行向上转换,(显示意图)
        • 首选使用 dynamic_cast 进行向下转换,并检查返回值。

        如果 downcast 的 static_cast 没有危险,则可以取消后一条规则。

        【讨论】:

        • 请注意,“始终使用dynamic_cast 进行向下转换”仅在基类始终为多态时才有效。所以它依赖于另一个样式规则,“只向上转换为多态基”。第二条规则在很多项目中都有意义,但并非必然全部。
        • @SteveJessop 但如果基类不是多态的,则 dynamic_cast 只会返回 nullptr 。 (当然用起来也没多大意义)
        • “始终使用dynamic_cast 进行向下转换”是错误的。在某些合理的情况下,您在编译时就知道强制转换成功并且您应该使用static_cast 明确该假设。不这样做客观上是不好的。
        • @KonradRudolph 我已将“总是”编辑为“更喜欢”。还是觉得很不对劲吗?
        • @StephaneRolland 我可以忍受。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多