Implementing Inheritance 375
12
29:
30: class Dog : public Mammal
31: {
32: public:
33:
34: // Constructors
35: Dog();
36: ~Dog();
37:
38: // Accessors
39: BREED GetBreed() const;
40: void SetBreed(BREED);
41:
42: // Other methods
43: WagTail();
44: BegForFood();
45:
46: protected:
47: BREED itsBreed;
48: };
This program has no output because it is only a set of class declarations without their
implementations. Nonetheless, there is much to see here.
On lines 7–28, the Mammalclass is declared. Note that in this example,Mammal
does not derive from any other class. In the real world, mammals do derive—that
is, mammals are kinds of animals. In a C++ program, you can represent only a fraction
of the information you have about any given object. Reality is far too complex to capture
all of it, so every C++ hierarchy is a carefully limited representation of the data available.
The trick of good design is to represent the areas that you care about in a way that maps
back to reality in a reasonably faithful manner without adding unnecessary complication.
The hierarchy has to begin somewhere; this program begins with Mammal. Because of this
decision, some member variables that might properly belong in a higher base class are
now represented here. Certainly all animals have an age and weight, for example, so if
Mammalis derived from Animal, you would expect to inherit those attributes. As it is, the
attributes appear in the Mammalclass.
In the future, if another animal sharing some of these features were added (for instance,
Insect), the relevant attributes could be hoisted to a newly created Animalclass that
would become the base class of Mammaland Insect. This is how class hierarchies evolve
over time.
LISTING12.1 continued
ANALYSIS