I am trying to learn about dynamic casting in C++.
So I have developed 2 classes to test some things related to dynamic casting:
class Entity {
protected:
int x = 10;
public:
virtual void f1() { cout << "f1 from Entity class" << endl; }
};
class Player : public Entity {
public:
void f1() { cout << "f1 from Player class" << endl; }
int f2() { return x; }
void f3() { cout << "f3 from Player class" << endl; }
};
The method f2()
returns x that is defined in the Parent Class Entity
.
And here is the main
:
int main() {
Entity* e = new Entity;
Player* p = dynamic_cast<Player*>(e);
cout << p->f2() << endl;
//the program prints : "p is not null"
if(p == nullptr)
cout << "p is null";
else
cout << "p is not null";
return 0;
}
An exception is thrown when calling p->f2()
, specifically on line return x;
and it says:
Exception thrown: read access violation. this was nullptr.
The strange thing here is that x
is a protected variable, so it must exist at
Entity and Player objects, but after the dynamic casting from Entity to Player, the new object can not access it.
So what is the exception reason?
Note: When doing static casting instead of dynamic, p->f2()
gives 10 normally
dynamic_cast
will never lie. It checks the runtime type of the object to see if it matches the T
gi8ven in the dynamic_cast<T>
. You created an instance of the Entity
base class. The runtime type of this object is Entity
because that's what you created.
dynamic_cast
knows the runtime type of the object, so it knows dynamic_cast<Player*>
cannot work since the object isn't a Player
object. Therefore, it returns nullptr
.
static_cast
doesn't know if the object is a Player
or not; it assumes that it is and returns a pointer to that object if it is there. But since it's not there, any attempt to use the result of the static_cast
yields undefined behavior.
Which just so happens to do what you want, but there's no guarantee of that.