22.8 Parent and child class data

A parent class is a subset of a child class; that is, the child class includes all of the data members and methods as the parent. It's common also to speak of a parent class as a base class, and to speak of a child class as a derived class.

In order to allow the child class to have access to the private fields and methods of the parent class we need to declare those fields to be protected rather than private.

What about access to the public fields of the parent? The child can always access these, but these fields do not necessarily have to be public members of the child as well. A child can change a parent method from protected to public or from public to protected by redeclaring it.

In the declaration of a child class, you follow the child class's name by a colon, an access specifier, and the name of the parent class, like class cMyChild : public cMyParent.

We usually stick the word public in there because otherwise the access permissions will default to the default C++ value of private, which is not as commonly used. In particular, if you don't put in the public, then all of the parent's public methods are now private methods of the child.

Why would you ever want to use private inheritance anyway? This is appropriate when you have defined a class that is a specialization of a parent class that has some methods you don't want your code-users to be able to invoke.

Here's a specific example. We use a class called a cBiota which holds a bunch of cCritter * pointers to lively little cCritter objects. Now cBiota actually inherits from a special kind of MFC class called CObArray which encapsulates the notion of an array of pointers to objects. The CObArray has standard array methods such as GetSize(), operator[], and a method Add() for adding things to the end of the array. Now suppose that when you Add an element to the cBiota, you want to be sure to do some kind of branding on the element, like, say, giving it an internal pointer to the cBiota itself. So if we had a cBiota _biome and a cCritter* pcritter, we might write a line like _biome.Add(pcritter), but we might not want to be able to write a line like _biome[_biome.GetSize()-1] = pcritter;. Now if in this case you want to prevent yourself and the other programmers you work with from using all of the possible CObArray methods, you can declare class cBiota : private CObArray. And then down inside the cBiota definition, you can specify the Add method as public, and override it to do the critter-branding.

The author recently stumbled across an odd gotcha related to parent and child classes. C++will let you declare a child class member with the same name as a parent class member. If you do this, your child class can be changing the value of this field, but when you use a parent class accessor to look at what you think is the same field, you'll get back the default value that lives in the parent class. In this situation, the parent field is said to 'shadow' (as in 'cover up') the child field. Here's an illustration.

class cSprite 
    Real _radius; //Assume the constructor sets this to 0.0 
    Real radius(){return _radius;} 
class cPolygon : public cSprite 
    Real _radius; 
    Real makeRegularPolygon(int vertexcount, Real radius) 
cPolygon poly; 
poly.makeRegularPolygon(5, 2.0);//Changes cPolygon _radius to 2.0 
Real polyradius = poly.radius(); //Makes polyradius 0.0, not 2.0! 

    Part I: Software Engineering and Computer Games
    Part II: Software Engineering and Computer Games Reference