Public inheritance, initialization of the base class, order of construction/destruction, type double.
Another important relationship between objects is the "is-a" relationship. When we say that a star is a celestial body, we mean that a star has all the properties of a celestial body, and maybe some others, specific to a star. In C++ this relationship is expressed using inheritance. We can say: class Star inherits from class CelestialBody, or that CelestialBody is the base class of Star.
Figure 5 Graphical representation the is-a relationships between objects.
Here's an example:
#include <iostream>
class CelestialBody
{
public:
CelestialBody (double mass)
: _mass (mass)
{
std::cout << "Creating celestial body of mass " << _mass << "\n";
}
~CelestialBody ()
{
std::cout << "Destroying celestial body of mass " <<
_mass << "\n";
}
private:
const double _mass;
};
class Star: public CelestialBody // Star is a CelestialBody
{
public:
Star (double mass, double brightness)
: CelestialBody (mass), _brightness (brightness)
{
std::cout << "Creating a star of brightness " <<
_brightness << "\n";
}
~Star ()
{
std::cout << "Destroying a star of brightness " <<
_brightness << "\n";
}
private:
const double _brightness;
};
int main ()
{
std::cout << " Entering main.\n";
Star aStar ( 1234.5, 0.1 );
std::cout << " Exiting main.\n";
}
The line
class Star: public CelestialBody // Star is a CelestialBodytells the compiler that Star inherits everything from CelestialBody. In particular, since CelestialBody has _mass, Star will have _mass, too.
CelestialBody has a constructor that requires an argument of the type double. Double is a built in type corresponding to double precision floating point numbers. Its single precision counterpart is called a float. Notice that our clever object std::cout has no problem printing doubles.
In the preamble to the constructor of Star we have to pass the argument to the constructor of CelestialBody. Here's how we do it-we invoke the base constructor using the name of its class:
Star (double mass, double brightness)
: CelestialBody (mass), _brightness (brightness)
|
Understanding the order of construction is very important.
The construction of the derived class proceeds in the usual order: first the embeddings, then the code in the constructor. Again, the order in the preamble is meaningless, and if there are no explicit initializations the whole thing may be omitted. I could have written the preamble in the reverse order:
Star (double mass, double brightness)
: _brightness (brightness), CelestialBody (mass)
|
The order of destruction is again the reverse of the order of construction. In particular, the derived class destructor is called first, the destructor of the base class follows.