Online Book Reader

Home Category

Professional C__ - Marc Gregoire [132]

By Root 1520 0
<< endl;

}

The logObject() function first writes the name of the object’s class to the file, followed by its log message. This way, when you read the log later, you can see which object was responsible for every line of the file.

If you are using typeid other than for logging and debugging purposes, consider reimplementing it using virtual methods.

Non-Public Inheritance

In all previous examples, parent classes were always listed using the public keyword. You may be wondering if a parent can be private or protected. In fact it can, though neither is as common as public.

Declaring the relationship with the parent to be protected means that all public and protected methods and data members from the superclass become protected in the context of the subclass. Similarly, specifying private access means that all public, protected, and private methods and data members of the superclass become private in the subclass.

There are a handful of reasons why you might want to uniformly degrade the access level of the parent in this way, but most reasons imply flaws in the design of the hierarchy. Some programmers abuse this language feature, often in combination with multiple inheritance, to implement “components” of a class. Instead of making an Airplane class that contains an engine data member and a fuselage data member, they make an Airplane class that is a protected engine and a protected fuselage. In this way, the Airplane doesn’t look like an engine or a fuselage to client code (because everything is protected), but it is able to use all of that functionality internally.

Non-public inheritance is rare and we recommend using it cautiously, if for no other reason than because most programmers are not familiar with it.

Virtual Base Classes

Earlier in this chapter, you learned about ambiguous base classes, a situation that arises when multiple parents each have a parent in common, as shown again in Figure 8-12. The solution that we recommended was to make sure that the shared parent doesn’t have any functionality of its own. That way, its methods can never be called and there is no ambiguity problem.

FIGURE 8-12

C++ has another mechanism for addressing this problem in the event that you do want the shared parent to have its own functionality. If the shared parent is a virtual base class, there will not be any ambiguity. The following code adds a sleep() method to the Animal base class and modifies the Dog and Bird classes to inherit from Animal as a virtual base class. Without the virtual keyword, a call to sleep() on a DogBird object would be ambiguous and would generate a compiler error because DogBird would have two subobjects of class Animal, one coming from Dog and one coming from Bird. However, when Animal is inherited virtually, DogBird has only one subobject of class Animal, so there will be no ambiguity with calling sleep().

class Animal

{

public:

virtual void eat() = 0;

virtual void sleep() { cout << "zzzzz...." << endl; }

};

class Dog : public virtual Animal

{

public:

virtual void bark() { cout << "Woof!" << endl; }

virtual void eat() { cout << "The dog has eaten." << endl; }

};

class Bird : public virtual Animal

{

public:

virtual void chirp() { cout << "Chirp!" << endl; }

virtual void eat() { cout << "The bird has eaten." << endl; }

};

class DogBird : public Dog, public Bird

{

public:

virtual void eat() { Dog::eat(); }

};

int main()

{

DogBird myConfusedAnimal;

myConfusedAnimal.sleep(); // Not ambiguous because Animal is virtual

return 0;

}

Virtual base classes are a great way to avoid ambiguity in class hierarchies. The only drawback is that many C++ programmers are unfamiliar with the concept.

SUMMARY


This chapter has covered numerous details about inheritance. You have learned about its many applications, including code reuse and polymorphism. You have also learned about its many abuses, including poorly-designed multiple inheritance schemes. Along the way, you’ve uncovered some cases that require special attention.

Inheritance is a powerful language feature

Return Main Page Previous Page Next Page

®Online Book Reader