首页 > 解决方案 > dynamic_cast 到派生类返回 nullptr

问题描述

在下面的代码中,为什么不dynamic_cast产生Base *?

#include <cassert>

class BaseI;

class SystemI {
public:
    virtual ~SystemI() {}
    virtual void remove(BaseI *) = 0;
};

class BaseI {
public:
    SystemI * system = nullptr;
    virtual ~BaseI() {
        system->remove(this);
    }
};

class Base : public BaseI { };

class System : public SystemI {
public:
    System() {
        Base base;
        base.system = this;
    }
    void remove(BaseI * basei) override {
        Base * base = dynamic_cast<Base *>(basei);
        assert(base != nullptr); // <-------------------- fails
    }
};

int main() {
    System sys;
}

我的意图是创建一种机制,其中派生的组件BaseI在删除时自动从系统中删除。

标签: c++

解决方案


在 C++ 中,派生类对象的“派生性”在基类析构函数开始运行之前被销毁。因此,当Base对象超出范围时,它的(空)析构函数Base::~Base首先运行;一旦完成,就没有Base对象了,但仍然有一个BaseI对象,必须随后销毁。BaseI::~BaseI因此,当运行并调用remove时,动态转换Base*必须失败。


推荐阅读