Search code examples
c++inheritancedynamic-castdowncast

dynamic_cast "this" to derived type: when is it legal?


Here is a code that obviously doesn't work, since downcasting "this" in a constructor is illegal:

#include <cassert>

class A {
protected:
        virtual ~A() {}
public:
        A();
};

class B : public A {
};

A::A() {
        assert(dynamic_cast<B*>(this));
}

int main(void) {
        B b;
        return 0;
}

As expected, when compiled with g++, the assertion fails.

Here is another code that, however, works (with g++ 4.7, at least, I haven't tried other compilers):

#include <cassert>

class A {
protected:
        virtual ~A() {}
public:
        A() {}
        void f();
};

class B : public A {
public:
        B() {
                f();
        }
};

void A::f() {
        assert(dynamic_cast<B*>(this));
}

int main(void) {
        B b;
        return 0;
}

My question is: is the second code "legal", i.e. can I expect that for any compiler it will work that way?

My intuition is that since f() is called from the body of B's constructor, "b" is already well formed as an instance of type B, which makes the code legal. Yet, I'm still kind of dynamic_casting "this" from a constructor...

(note that my question is not whether this is good practice or not, just if it's legal).


Solution

  • Yes, the second example is well defined, and the cast will succeed. During the constructor of B, the dynamic type of the object is B, so a cast to B* will succeed.

    In the first example, as you say, in the constructor of A the dynamic type is A, so a cast to B* will fail.