class Parent {
public:
void sleep() {cout<<"Paren::sleep";}
};
class Child: public Parent {
public:
void gotoSchool(){cout<<"chil::gotoSchool";}
};
int main( )
{
Parent parent;
Child child;
// upcast - implicit type cast allowed
Parent *pParent = &child; //OK.
// downcast - explicit type case required
Child *pChild = (Child *) &parent; //OK due to typecast but not safe when we call child specific method
pParent -> sleep();
pChild -> gotoSchool(); //Undefined but works ok on VS08
return 0;
}
Question:
In the above code pChild -> gotoSchool(); is undefined as per standard. By the word undefined , it means it may or may not work. It worked for me. But my question is why did it work? It shouldn't have. I cannot visualize the layout object in memory.
//Parent object doesn't even know anything about gotoSchool method, so how come a pointer to Parent object still prints gotoSchool. The question here is not about the undefined behavior, its more about how can it even know about the gotoSchool method, so even by sheer luck it shouldnt call the gotoSchool method to print Child::gotoSchool.
Parent Child
----------- -------------
| | | |
| sleep | | sleep |
| | | gotoSchool|
----------- -------------
Ofcourse the object doesnt contain inside it the member functions but only data members. The above diagram is just for explanation.
But my question is why did it work?
Because the way your compiler was implemented happens to lead to that behaviour.
It shouldn't have.
If you mean that a compiler shouldn't allow that behaviour, well... standard doesn't require that.
It may, it can, and it did.
How it works
I don't have the source code of visual studio at hand so I can't tell you exactly how it works. But generally speaking, member functions are implemented as regular functions, except with an extra parameter which contains the address of the object. The location of the function itself in the memory is not associated with the memory of the objects. The compiler knows exactly where the code for the function is.
You might even be able to do ((Child*)nullptr)->gotoSchool(); and observe the same (undefined) behaviour.
There is no obvious reason why it couldn't have the observed behaviour.
I cannot visualize the layout object in memory
The memory layout of the object is irrelevant to the function because the function never uses any of the object's memory.
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