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).
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.
My question is: is the second code "legal"
Yes, it's fine.
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
It's legal anyway, but this is the reason the assert succeeds rather than failing: by the time you're in the body of B
's constructor, you have an instance of type B
Yet, I'm still kind of dynamic_casting "this" from a constructor...
Note that A::f
is statically well-formed wherever you call it from - it would just dynamically fail the assert if called from A::A
. You could also instantiate an A
and call f
directly on it (since A
isn't abstract) - that would still be well-formed, but would fail the assert.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With