I asked a question an hour or two ago that is similar but this is fundamentally different to me. After this I should be good.
class base
{
private:
string tame;
public:
void kaz(){}
virtual ~base() {}
void print() const
{
cout << tame << endl;
}
};
class derived: public base
{
private:
string taok;
public:
std::string name_;
explicit derived( const std::string& n ) : name_( n ) {}
derived(){}
void blah(){taok = "ok";}
void print() const
{
std::cout << "derived: " << name_ << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
base b;
derived d;
base * c = &b;
derived * e = (derived *)&b;
e->kaz();
system("pause");
return 0;
}
I know downcasting in in this example is not good practice but I’m just using it as an example. So when I now am pointing to a base object from a derived pointer, I don’t get why I am still able to do certain operations only belonging to the base class.
For example, the base class’s interface has a Kaz() method but the derived method does not. When I downcast, why does the compiler not yell at me for doing this even though Kaz() is not part of the derived class’s interface?
-
Why is the compiler not complaining for using members of the base class when I am using a derived pointer?
-
Why does the compiler yell at me only when I access a member from the base class interface from within a method but not directly?
For example:
I can’t do this:
e->print() //Program crashes
But I can do this:
e->tame = "Blah";
cout << e->tame << endl;
The derived class inherits all the members of the base class, so
kaz()exists also forderivedobjects. If you callkaz()on aderivedobject, simply the method that was inherited frombaseis called. If you access the inherited members from within a method or directly doesn’t matter.The problem with
eis that it is really pointing to abaseobject, not aderived. With the caste = (derived *)&byou tell the compiler “I know it doesn’t look like it, but this really is aderived *, believe me!”. And the compiler believes you, since you are the master. But you lied and&bwas actually not aderived*. Therefore horrible things happen when the compiler tries to callderived::print()on it, in this case it leads to a crash of the program.When you access
e->tamedirectly, also horrible things could happen (the compiler still treatseas aderived*while it only is abase*). In this case, by chance, it happens to print out the expected value anyway.