You have a A *
that is pointing to an instance of A
, not A *
that is actually pointing to an instance of B
. That is why dynamic_cast
returns a null pointer of type B *
, it is not related to these being incomplete types or anything (in the linked code, both A
and B
are complete types), and thus this is defined behaviour for dynamic_cast
. However after that a null pointer is accessed; a clever compile can know that dynamic_cast
can fail at that point and the pb->func1();
can do anything including not causing a null pointer exception or anything at all, or even calling the pb1->func
on something that is not B
.
An example with an incomplete type would be:
#include <iostream>
using namespace std;
class A {
public:
virtual void func() {
cout << "func():: in class A" << endl;
}
void func1(){
cout<< "func1():: in class A";
}
};
class B;
int main() {
A a;
A* pa = &a;
B* pb = dynamic_cast<B*>(pa);
return 0;
}
Now if you compile this with G++, you get
y.cc: In function ‘int main()’:
y.cc:20:32: error: cannot dynamic_cast ‘pa’ (of type ‘class A*’) to
type ‘class B*’ (target is not pointer or reference to complete type)
B* pb = dynamic_cast<B*>(pa);
that is all sane C++ compilers will reject such code.