【问题标题】:downcasting dynamic_cast with non-polymorphic classes, why doesn't it compile?用非多态类向下转换 dynamic_cast,为什么它不编译?
【发布时间】:2013-03-14 12:02:42
【问题描述】:

我有以下代码:

using namespace std;

class BaseOk
{
public:
    virtual void ImplementMe()
    {
    };
};
class DerivedOk : public BaseOk
{
public:
    void ImplementMe()
    {
    }
};

class CBase { };
class CDerived: public CBase { };



int main() 
{ 
    CBase b; CBase* pb;
    CDerived d; CDerived* pd;

    pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
    pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived  -> this doesn't compile

    // Polymorphic case

    BaseOk b2; BaseOk* pb2;
    DerivedOk d2; DerivedOk* pd2;

    pb2 = dynamic_cast<BaseOk*>(&d2);     // ok: derived-to-base
    pd2 = dynamic_cast<DerivedOk*>(&b2);  // wrong: base-to-derived -> this returns a NULL pointer

}

带有指针“pd”的行执行向下转换,我同意它应该失败,因为结果是一个完全不同的对象。 我的问题是:为什么该行中的 dynamic_cast 根本不编译,而只是返回一个 NULL 指针?

我正在使用 MSVC2012 编译器

【问题讨论】:

标签: c++ class dynamic-cast downcast


【解决方案1】:

为什么该行中的 dynamic_cast 根本不编译,而不是 只是返回一个 NULL 指针?

将此视为一项功能/功能,而不是限制。

dynamic_cast 是一种基于指针/引用查找对象的 RTTI(运行时类型信息)的机制。
现在假设如果一个类根本不是多态的(即不包含任何virtual 方法),那么dynamic_cast 肯定会总是失败
这意味着您不必使用dynamic_cast,通过的概率为0。 为什么要在编译时已知的东西上浪费机器周期?这就是编译器立即为您提供便利的原因。

这还有另一个隐藏的优势。假设您正在使用 dynamic_cast 和引用,如果失败则抛出异常。有人愿意为编译时已知的东西处理异常吗?

【讨论】:

    【解决方案2】:

    在指向非多态类型的指针上使用dynamic_cast 是错误的。这是一个可诊断的规则,所以你应该得到一个编译时错误。

    在指向不可转换为目标类型的多态类型的指针上使用它不是错误,并且在任何情况下通常在编译时都无法检测到。它具有明确定义的行为,给出一个空指针。

    【讨论】:

    • Using dynamic_cast on a pointer to a non-polymorphic type is an error ...我认为“错误”在这种情况下是不恰当的词。这是一个“总是假的”的微不足道的信息;通过编译错误通知用户。
    猜你喜欢
    • 1970-01-01
    • 2017-11-03
    • 2016-08-24
    • 2019-02-09
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 2020-12-16
    • 2012-03-17
    相关资源
    最近更新 更多