Before I explain this I want to be sure that you
READ MY NOTES AT THE BOTTOM, as I don't want to mislead you.
Consider the following:
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
|
struct Foo
{
int a;
};
void Func1(Foo* f)
{
cout << "Func1\n";
}
void Func2(Foo* f)
{
cout << "Func2 Enter\n";
f->a = 6;
cout << "Func2 Exit\n";
}
//======
int main()
{
Foo* f = 0; // a bad pointer
Func1(f);
Func2(f);
return 0;
}
|
Look what happens here. Func2 will explode on the
f->a = 6;
line for obvious reasons (f is a bad pointer), but Func1 will run just fine, even though f is a bad pointer.
The reason Func1 runs fine is because 'f' is never used in Func1. Therefore it doesn't matter that the pointer is bad.
non-virtual member functions in C++ basically operate the same way under the hood. The compiler just changes the syntax around a bit. It's basically like this:
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
|
// this code here:
struct Foo
{ int a; };
void PrintA(Foo* f)
{
cout << f->a;
}
//...
Foo* f;
PrintA(f);
// is pretty much the exact same thing as this code here:
struct Foo
{
int a;
void PrintA()
{
cout << this->a;
}
};
//...
Foo* f;
f->PrintA();
|
In the
f->PrintA();
example, 'f' is passed to the function as a parameter, just like it would be normally... only the compiler sort of hides that from you. 'f' becomes the 'this' pointer in the function. So when you cout
this->a
you're really outputting
f->a
.
Note that if 'this' isn't used, there's no problem.... as is the case in the Func1 example in this post, and the bad cast example in your original post. Both work just fine because the bad pointer is never used.
virtual functions, on the other hand, always use the this pointer (they have to in order to use the vtable to determine which class's function to call), which is why your original program explodes when you change 'hello' to be a virtual function. The bad pointer is now being used... and since it's bad, it causes problems.
==================================================
READ THESE NOTES
==================================================
My above examples are
conceptual only. And while they may compile and run as you expect on your compiler,
the C++ standard does not say that must always be the case.
It is theoretically possible for non-virtual functions to use the 'this' pointer somehow without you knowing it... therefore this is
never safe to do