0

In the following code, why doesn't dynamic_cast produce a 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;
}

My intent is to create a mechanism where components derived from BaseI automatically remove themselves from the system upon deletion.

Anonymous Entity
  • 3,254
  • 3
  • 27
  • 41

1 Answers1

4

In C++, a derived class object's "derivedness" is destroyed before the base class destructor starts to run. Thus, when the Base object goes out of scope, its (empty) destructor Base::~Base runs first; once this has completed, there is no Base object anymore, but there is still a BaseI object, which must subsequently be destroyed. When BaseI::~BaseI runs, therefore, and calls remove, the dynamic cast to Base* must fail.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312