Basically, you told the compiler that m is pointing at a manager object, and it believes you, and it treats that object as if it's a Manager object, and these objects are so simple that it didn't crash. This is very dangerous and a very bad idea, but C++ trusts you to know what you're doing when it comes to memory.
You have created a pointer to a Manager, called m.
You have pointed that pointer at an object. You've pointed it at an object that happens to be of type CEO, but this is C++ and if you want to make a pointer point at something, you can do that. I don't remember the rules for exactly when you can and cannot static_cast a pointer to a different kind of pointer (I never do it; static_cast of a pointer generally means something has gone very wrong in the design); looks like this case is permitted.
So now you've got a pointer-to-Manager, pointing at an object of type CEO.
Then, you call a function through that pointer. The function you call is effectively this function:
Manager::printData( Manager* this)
It's "call this function, named printData, on THAT object over there" The compiler will check that the object is of a class that has such a function, but in this case, everythign's fine - it does, because the object is a Manager object. It must be, right? That's what you told it the object was.
This is how C++ class functions work, in practice. So what happens next?
cout << "print data from manager" << data << endl;
What is data? It's a value inside the object. A piece of memory. So what gets output? Whatever happens to be in that memory.
Here, run this code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
#include <iostream>
using namespace std;
class Employee{
public:
virtual void f(){}
};
class Manager : public Employee{
public:
int data;
int dataTwo;
void printData(){
cout << "print data from manager" << data << endl;
}
};
class CEO : public Employee{
public:
int moreData;
double d;
CEO() : moreData(7){}
};
int main()
{
Employee* e = new CEO;
Manager* m = static_cast<Manager*>(e);
cout << "Address of CEO object: " << e << '\n';
cout << "Location Manager pointer is pointing at: " << m << '\n';
m->printData();
}
|
See what happens with this code? You (probably) see the number 7 output. You're calling the function printData() on what you have told the compiler is a Manager object, but it isn't really, is it?
the CEO object in memory has no member function printData() so how is this function even executed? |
NO object in memory has a member function printData() - there is ONE function printData somewhere, and that same function is used every time it's called. You told the compiler to execute the function on an object that you said was a Manager object. The compiler believed you.