Ehhhhhhh..... that example isn't really correct. Virtual functions exist to get around that kind of problem.
The only case in which you should ever need to downcast is when pulling an object out of a generic container.
- Let's say you have a chest which contains a sword (CSword) and a shield (CShield).
- CSword : public CObject, and CShield : public CObject.
- CChest is a container implemented as a vector of CObjects.
- When you put an object into the chest, it is cast up to a CObject.
- When you take an object out of the chest, you have to downcast it.
The problem is... even though downcasting makes it technically feasable to do, it's still a pretty icky situation to deal with. Just creating a new object means going back to every downcast and making sure it's accounted for.
It may be preferable to just deal with everything as the base class.
An illustration of the weight() example solved:
Code:
#include <iostream>
class HasMass {
public:
HasMass (int mass) : myWeight(mass) { }
virtual int weight() const { return myWeight; }
private:
int myWeight;
};
class Weight : public HasMass {
public:
Weight (int W) : HasMass(W) { }
};
class Container : public HasMass {
public:
Container() : HasMass(1), contained(0) { }
virtual int weight() const { return HasMass::weight() + contained->weight(); }
virtual void add (HasMass * addMe) { contained = addMe; }
private:
HasMass * contained;
};
void printMasses (HasMass const & A, HasMass const & B, HasMass const & C) {
std::cout << A.weight() << " " << B.weight() << " " << C.weight() << '\n';
}
int main (void) {
Weight oz(1);
Weight lb(16);
Container C;
C.add (&lb);
std::cout << oz.weight() << " " << lb.weight() << " " << C.weight() << '\n';
printMasses (oz, lb, C);
return 0;
}