在以下代码中,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
的组件在删除后会自动从系统中删除。
答案 0 :(得分:5)
在C ++中,派生类对象的“派生性”在基类析构函数开始运行之前被销毁。因此,当Base
对象超出范围时,其(空)析构函数Base::~Base
首先运行;完成此操作后,将不再有Base
对象,但仍然有一个BaseI
对象,随后必须将其销毁。因此,当BaseI::~BaseI
运行并调用remove
时,向Base*
的动态转换必须失败。