使用非多态类转发dynamic_cast,为什么不编译?

时间:2013-03-14 12:02:43

标签: c++ class dynamic-cast downcast

我有以下代码:

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编译器

2 个答案:

答案 0 :(得分:2)

  

为什么该行中的dynamic_cast根本没有编译   只返回一个NULL指针?

将此视为功能/设施而非限制。

dynamic_cast是一种机制,我们可以根据指针/引用找到对象的RTTI(运行时类型信息)。
现在假设一个类完全没有多态(即不包含任何virtual方法),那么dynamic_cast 总是会失败。 这意味着你不必使用传递概率为0的dynamic_cast为什么要在编译时知道的事情上浪费机器周期?这就是为什么编译器会立即为您提供设施。

这还有另一个隐藏的优势。假设您正在使用带有引用的dynamic_cast,如果它失败则抛出异常。是否有人想要处理在编译时已知的事情的异常!

答案 1 :(得分:2)

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

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