使用dynamic_cast的奇怪行为

strange behaviour using dynamic_cast

本文关键字:dynamic cast 使用      更新时间:2023-10-16

我在试验dynamic_cast时偶然发现了一些奇怪的行为。这是我的代码

struct Base
{
    virtual ~Base(){}    
    virtual void output() = 0;
};
struct Derived1 : public Base
{
    void output() {}    
    void doDerived_1()
    {
        std::cout << "derived 1n";
    }
};
struct Derived2: public Base
{ 
    void output() {}
    void doDerived_2()
    {
        std::cout << "derived 2n";
    }
};     
int main()
{
    Base* base = new Derived1();
    Derived2* der2 = dynamic_cast<Derived2*>(base);
    // der2 = 0
    der2->doDerived_2();
}

即使der2等于0,doDerived_2()仍然会被调用,其中的任何代码都将被执行。当我调用output()函数时,代码中断。

谁能给我解释一下为什么这工作,而没有打破,当它显然应该?由于

你的代码有未定义的行为,因为你正在解引用一个空指针。

然而,成员函数调用的一种可能实现是通过thiscall调用约定,该约定隐式地传递对象指针作为第一个参数。如果函数不访问任何成员变量,则this指针不会解引用,函数可能会按预期执行。它与dynamic_cast没有任何关系。

请注意,在标准

中不能保证这一点。

的例子:

struct Foo {
    int doIt() {return 42;}
};
int main() {
    Foo *f = NULL;
    std::cout << f->doIt();
}

一些编译器上打印42

您正在解引用空指针。这种操作的行为是未定义的。在这种情况下,碰巧调用this为空指针的方法。然而,任何事情都有可能发生。

如果你想要抛出一个异常,转换引用:

Derived2& der2 = dynamic_cast<Derived2&>(*base);
der2.doDerived_2();

或者,您可以使用if语句仅在强制转换成功时执行某些代码:

if (Derived2* der2 = dynamic_cast<Derived2*>(base)) {
    der2->doDerived_2();
}