Back to Item 42: Use private inheritance judiciously.
Continue to Item 44: Say what you mean; understand what you're saying.

Item 43: Use multiple inheritance judiciously.

Depending on who's doing the talking, multiple inheritance (MI) is either the product of divine inspiration or the manifest work of the devil. Proponents hail it as essential to the natural modeling of real-world problems, while critics argue that it is slow, difficult to implement, and no more powerful than single inheritance. Disconcertingly, the world of object-oriented programming languages remains split on the issue: C++, Eiffel, and the Common LISP Object System (CLOS) offer MI; Smalltalk, Objective C, and Object Pascal do not; and Java supports only a restricted form of it. What's a poor, struggling programmer to believe?

Before you believe anything, you need to get your facts straight. The one indisputable fact about MI in C++ is that it opens up a Pandora's box of complexities that simply do not exist under single inheritance. Of these, the most basic is ambiguity (see Item 26). If a derived class inherits a member name from more than one base class, any reference to that name is ambiguous; you must explicitly say which member you mean. Here's an example that's based on a discussion in the ARM (see Item 50):

    class Lottery {
    public:
      virtual int draw();

      ...

    };

    class GraphicalObject {
    public:
      virtual int draw();

      ...

    };

    class LotterySimulation: public Lottery,
                             public GraphicalObject {

      ...                          // doesn't declare draw

    };

    LotterySimulation *pls = new LotterySimulation;

    pls->draw();                   // error! — ambiguous
    pls->Lottery::draw();          // fine
    pls->GraphicalObject::draw();  // fine

This looks clumsy, but at least it works. Unfortunately, the clumsiness is difficult to eliminate. Even if one of the inherited `draw` functions were private and hence inaccessible, the ambiguity would remain. (There's a good reason for that, but a complete explanation of the situation is provided in Item 26, so I won't repeat it here.)

Explicitly qualifying members is more than clumsy, however, it's also limiting. When you explicitly qualify a virtual function with a class name, the function doesn't act virtual any longer. Instead, the function called is precisely the one you specify, even if the object on which it's invoked is of a derived class:

    class SpecialLotterySimulation: public LotterySimulation {
    public:
      virtual int draw();

      ...

    };

    pls = new SpecialLotterySimulation;

    pls->draw();                        // error! — still ambiguous
    pls->Lottery::draw();               // calls Lottery::draw
    pls->GraphicalObject::draw();       // calls GraphicalObject::draw

In this case, notice that even though `pls` points to a `SpecialLotterySimulation` object, there is no way (short of a downcast — see Item 39) to invoke the `draw` function defined in that class.

But wait, there's more. The `draw` functions in both `Lottery` and `GraphicalObject` are declared virtual so that subclasses can redefine them (see Item 36), but what if `LotterySimulation` would like to redefine both of them? The unpleasant truth is that it can't, because a class is allowed to have only a single function called `draw` that takes no arguments. (There is a special exception to this rule if one of the functions is `const` and one is not — see Item 21.)

At one point, this difficulty was considered a serious enough problem to justify a change in the language. The ARM discusses the possibility of allowing inherited virtual functions to be "renamed," but then it was discovered that the problem can be circumvented by the addition of a pair of new classes:

    class AuxLottery: public Lottery {
    public:
      virtual int lotteryDraw() = 0;

      virtual int draw() { return lotteryDraw(); }
    };

    class AuxGraphicalObject: public GraphicalObject {
    public:
      virtual int graphicalObjectDraw() = 0;

      virtual int draw() { return graphicalObjectDraw(); }
    };

    class LotterySimulation: public AuxLottery,
                             public AuxGraphicalObject {
    public:
      virtual int lotteryDraw();
      virtual int graphicalObjectDraw();

      ...

    };

Each of the two new classes, `AuxLottery` and `AuxGraphicalObject`, essentially declares a new name for the `draw` function that each inherits. This new name takes the form of a pure virtual function, in this case `lotteryDraw` and `graphicalObjectDraw`; the functions are pure virtual so that concrete subclasses must redefine them. Furthermore, each class redefines the `draw` that it inherits to itself invoke the new pure virtual function. The net effect is that within this class hierarchy, the single, ambiguous name `draw` has effectively been split into two unambiguous, but operationally equivalent, names: `lotteryDraw` and `graphicalObjectDraw`:

    LotterySimulation *pls = new LotterySimulation;

    Lottery *pl = pls;
    GraphicalObject *pgo = pls;

    // this calls LotterySimulation::lotteryDraw
    pl->draw();

    // this calls LotterySimulation::graphicalObjectDraw
    pgo->draw();

This strategy, replete as it is with the clever application of pure virtual, simple virtual, and inline functions (see Item 33), should be committed to memory. In the first place, it solves a problem that you may encounter some day. In the second, it can serve to remind you of the complications that can arise in the presence of multiple inheritance. Yes, this tactic works, but do you really want to be forced to introduce new classes just so you can redefine a virtual function? The classes `AuxLottery` and `AuxGraphicalObject` are essential to the correct operation of this hierarchy, but they correspond neither to an abstraction in the problem domain nor to an abstraction in the implementation domain. They exist purely as an implementation device — nothing more. You already know that good software is "device independent." That rule of thumb applies here, too.

The ambiguity problem, interesting though it is, hardly begins to scratch the surface of the issues you'll confront when you flirt with MI. Another one grows out of the empirical observation that an inheritance hierarchy that starts out looking like this,

has a distressing tendency to evolve into one that looks like this:

Now, it may or may not be true that diamonds are a girl's best friend, but it is certainly true that a diamond-shaped inheritance hierarchy such as this is not very friendly. If you create a hierarchy such as this, you are immediately confronted with the question of whether to make `A` a virtual base class, i.e., whether inheritance from A should be virtual. In practice, the answer is almost invariably that it should; only rarely will you want an object of type `D` to contain multiple copies of the data members of `A`. In recognition of this truth, `B` and `C` above declare `A` as a virtual base class.

Unfortunately, at the time you define `B` and `C`, you may not know whether any class will decide to inherit from both of them, and in fact you shouldn't need to know this in order to define them correctly. As a class designer, this puts you in a dreadful quandary. If you do not declare `A` as a virtual base of `B` and `C`, a later designer of `D` may need to modify the definitions of `B` and `C` in order to use them effectively. Frequently, this is unacceptable, often because the definitions of `A`, `B`, and `C` are read-only. This would be the case if `A`, `B`, and `C` were in a library, for example, and `D` was written by a library client.

On the other hand, if you do declare `A` as a virtual base of `B` and `C`, you typically impose an additional cost in both space and time on clients of those classes. That is because virtual base classes are often implemented as pointers to objects, rather than as objects themselves. It goes without saying that the layout of objects in memory is compiler-dependent, but the fact remains that the memory layout for an object of type `D` with `A` as a nonvirtual base is typically a contiguous series of memory locations, whereas the memory layout for an object of type `D` with `A` as a virtual base is sometimes a contiguous series of memory locations, two of which contain pointers to the memory locations containing the data members of the virtual base class:

Even compilers that don't use this particular implementation strategy generally impose some kind of space penalty for using virtual inheritance.

In view of these considerations, it would seem that effective class design in the presence of MI calls for clairvoyance on the part of library designers. Seeing as how run-of-the-mill common sense is an increasingly rare commodity these days, you would be ill-advised to rely too heavily on a language feature that calls for designers to be not only anticipatory of future needs, but downright prophetic (see also M32).

Of course, this could also be said of the choice between virtual and nonvirtual functions in a base class, but there is a crucial difference. Item 36 explains that a virtual function has a well-defined high-level meaning that is distinct from the equally well-defined high-level meaning of a nonvirtual function, so it is possible to choose between the two based on what you want to communicate to writers of subclasses. However, the decision whether a base class should be virtual or nonvirtual lacks a well-defined high-level meaning. Rather, that decision is usually based on the structure of the entire inheritance hierarchy, and as such it cannot be made until the entire hierarchy is known. If you need to know exactly how your class is going to be used before you can define it correctly, it becomes very difficult to design effective classes.

Once you're past the problem of ambiguity and you've settled the question of whether inheritance from your base class(es) should be virtual, still more complications confront you. Rather than belaboring things, I'll simply mention two other issues you need to keep in mind:

- Passing constructor arguments to virtual base classes. Under nonvirtual inheritance, arguments for a base class constructor are specified in the member initialization lists of the classes that are immediately derived from the base class. Because single inheritance hierarchies need only nonvirtual bases, arguments are passed up the inheritance hierarchy in a very natural fashion: the classes at level n of the hierarchy pass arguments to the classes at level n-1. For constructors of a virtual base class, however, arguments are specified in the member initialization lists of the classes that are most derived from the base. As a result, the class initializing a virtual base may be arbitrarily far from it in the inheritance graph, and the class performing the initialization can change as new classes are added to the hierarchy. (A good way to avoid this problem is to eliminate the need to pass constructor arguments to virtual bases. The easiest way to do that is to avoid putting data members in such classes. This is the essence of the Java solution to the problem: virtual base classes in Java (i.e., "Interfaces") are prohibited from containing data.)
- Dominance of virtual functions. Just when you thought you had ambiguity all figured out, they change the rules on you. Consider again the diamond-shaped inheritance graph involving classes `A`, `B`, `C`, and `D`. Suppose that `A` defines a virtual member function `mf`, and `C` redefines it; `B` and `D`, however, do not redefine `mf`:

From our earlier discussion, you'd expect this to be ambiguous:

    D *pd = new D;
    pd->mf();                      // A::mf or C::mf?

Which `mf` should be called for a `D` object, the one directly inherited from `C` or the one indirectly inherited (via `B`) from `A`? The answer is that it depends on how `B` and `C` inherit from `A`. In particular, if `A` is a nonvirtual base of `B` or `C`, the call is ambiguous, but if `A` is a virtual base of both `B` and `C`, the redefinition of `mf` in `C` is said to dominate the original definition in `A`, and the call to `mf` through `pd` will resolve (unambiguously) to `C::mf`. If you sit down and work it all out, it emerges that this is the behavior you want, but it's kind of a pain to have to sit down and work it all out before it makes sense.

Perhaps by now you agree that MI can lead to complications. Perhaps you are convinced that no one in their right mind would ever use it. Perhaps you are prepared to propose to the international °C++ standardization committee that multiple inheritance be removed from the language, or at least to propose to your manager that programmers at your company be physically barred from using it.

Perhaps you are being too hasty.

Bear in mind that the designer of C++ didn't set out to make multiple inheritance hard to use, it just turned out that making all the pieces work together in a more or less reasonable fashion inherently entailed the introduction of certain complexities. In the above discussion, you may have noticed that the bulk of these complexities arise in conjunction with the use of virtual base classes. If you can avoid the use of virtual bases — that is, if you can avoid the creation of the deadly diamond inheritance graph — things become much more manageable.

For example, Item 34 describes how a Protocol class exists only to specify an interface for derived classes; it has no data members, no constructors, a virtual destructor (see Item 14), and a set of pure virtual functions that specify the interface. A Protocol `Person` class might look like this:

    class Person {
    public:
      virtual ~Person();

      virtual string name() const = 0;
      virtual string birthDate() const = 0;
      virtual string address() const = 0;
      virtual string nationality() const = 0;
    };

Clients of this class must program in terms of `Person` pointers and references, because abstract classes cannot be instantiated.

To create objects that can be manipulated as `Person` objects, clients of `Person` use factory functions (see Item 34) to instantiate concrete subclasses of that class:

    // factory function to create a Person object from a
    // unique database ID
    Person * makePerson(DatabaseID personIdentifier);

    DatabaseID askUserForDatabaseID();

    DatabaseID pid = askUserForDatabaseID();

    Person *pp = makePerson(pid);    // create object supporting
                                     // the Person interface

    ...                              // manipulate *pp via
                                     // Person's member functions

    delete pp;                       // delete the object when
                                     // it's no longer needed

This just begs the question: how does `makePerson` create the objects to which it returns pointers? Clearly, there must be some concrete class derived from `Person` that `makePerson` can instantiate.

Suppose this class is called `MyPerson`. As a concrete class, `MyPerson` must provide implementations for the pure virtual functions it inherits from `Person`. It could write these from scratch, but it would be better software engineering to take advantage of existing components that already do most or all of what's necessary. For example, let's suppose a creaky old database-specific class `PersonInfo` already exists that provides the essence of what `MyPerson` needs:

    class PersonInfo {
    public:
      PersonInfo(DatabaseID pid);
      virtual ~PersonInfo();

      virtual const char * theName() const;
      virtual const char * theBirthDate() const;
      virtual const char * theAddress() const;
      virtual const char * theNationality() const;

      virtual const char * valueDelimOpen() const;       // see
      virtual const char * valueDelimClose() const;      // below

      ...

    };

You can tell this is an old class, because the member functions return `const` `char*`s instead of `string` objects. Still, if the shoe fits, why not wear it? The names of this class's member functions suggest that the result is likely to be pretty comfortable.

You come to discover that `PersonInfo`, however, was designed to facilitate the process of printing database fields in various formats, with the beginning and end of each field value delimited by special strings. By default, the opening and closing delimiters for field values are braces, so the field value "Ring-tailed Lemur" would be formatted this way:

    [Ring-tailed Lemur]

In recognition of the fact that braces are not universally desired by clients of `PersonInfo`, the virtual functions `valueDelimOpen` and `valueDelimClose` allow derived classes to specify their own opening and closing delimiter strings. The implementations of `PersonInfo`'s `theName`, `theBirthDate`, `theAddress`, and `theNationality` call these virtual functions to add the appropriate delimiters to the values they return. Using `PersonInfo::name` as an example, the code looks like this:

    const char * PersonInfo::valueDelimOpen() const
    {
      return "[";                   // default opening delimiter
    }

    const char * PersonInfo::valueDelimClose() const
    {
      return "]";                   // default closing delimiter
    }

    const char * PersonInfo::theName() const
    {
      // reserve buffer for return value. Because this is
      // static, it's automatically initialized to all zeros
      static char value[MAX_FORMATTED_FIELD_VALUE_LENGTH];

      // write opening delimiter
      strcpy(value, valueDelimOpen());

      append to the string in value this object's name field

      // write closing delimiter
      strcat(value, valueDelimClose());

      return value;
    }

One might quibble with the design of `PersonInfo::theName` (especially the use of a fixed-size static buffer — see Item 23), but set your quibbles aside and focus instead on this: `theName` calls `valueDelimOpen` to generate the opening delimiter of the string it will return, then it generates the name value itself, then it calls `valueDelimClose`. Because `valueDelimOpen` and `valueDelimClose` are virtual functions, the result returned by `theName` is dependent not only on `PersonInfo`, but also on the classes derived from `PersonInfo`.

As the implementer of `MyPerson`, that's good news, because while perusing the fine print in the `Person` documentation, you discover that `name` and its sister member functions are required to return unadorned values, i.e., no delimiters are allowed. That is, if a person is from Madagascar, a call to that person's `nationality` function should return "Madagascar", not "[Madagascar]".

The relationship between `MyPerson` and `PersonInfo` is that `PersonInfo` happens to have some functions that make `MyPerson` easier to implement. That's all. There's no isa or has-a relationship anywhere in sight. Their relationship is thus is-implemented-in-terms-of, and we know that can be represented in two ways: via layering (see Item 40) and via private inheritance (see Item 42). Item 42 points out that layering is the generally preferred approach, but private inheritance is necessary if virtual functions are to be redefined. In this case, `MyPerson` needs to redefine `valueDelimOpen` and `valueDelimClose`, so layering won't do and private inheritance it must be: `MyPerson` must privately inherit from `PersonInfo`.

But `MyPerson` must also implement the `Person` interface, and that calls for public inheritance. This leads to one reasonable application of multiple inheritance: combine public inheritance of an interface with private inheritance of an implementation:

    class Person {                        // this class specifies
    public:                               // the interface to be
      virtual ~Person();                  // implemented

      virtual string name() const = 0;
      virtual string birthDate() const = 0;
      virtual string address() const = 0;
      virtual string nationality() const = 0;
    };

    class DatabaseID { ... };             // used below; details
                                          // are unimportant

    class PersonInfo {                    // this class has functions
    public:                               // useful in implementing
      PersonInfo(DatabaseID pid);         // the Person interface
      virtual ~PersonInfo();

      virtual const char * theName() const;
      virtual const char * theBirthDate() const;
      virtual const char * theAddress() const;
      virtual const char * theNationality() const;

      virtual const char * valueDelimOpen() const;
      virtual const char * valueDelimClose() const;

      ...

    };

    class MyPerson: public Person,        // note use of
                    private PersonInfo {  // multiple inheritance
    public:
      MyPerson(DatabaseID pid): PersonInfo(pid) {}

      // redefinitions of inherited virtual delimiter functions
      const char * valueDelimOpen() const { return ""; }
      const char * valueDelimClose() const { return ""; }

      // implementations of the required Person member functions
      string name() const
      { return PersonInfo::theName(); }

      string birthDate() const
      { return PersonInfo::theBirthDate(); }

      string address() const
      { return PersonInfo::theAddress(); }

      string nationality() const
      { return PersonInfo::theNationality(); }
    };

Graphically, it looks like this:

This kind of example demonstrates that MI can be both useful and comprehensible, although it's no accident that the dreaded diamond-shaped inheritance graph is conspicuously absent.

Still, you must guard against temptation. Sometimes you can fall into the trap of using MI to make a quick fix to an inheritance hierarchy that would be better served by a more fundamental redesign. For example, suppose you're working with a hierarchy for animated cartoon characters. At least conceptually, it makes sense for any kind of character to dance and sing, but the way in which each type of character performs these activities differs. Furthermore, the default behavior for singing and dancing is to do nothing.

The way to say all that in C++ is like this:

    class CartoonCharacter {
    public:
      virtual void dance() {}
      virtual void sing() {}
    };

Virtual functions naturally model the constraint that dancing and singing make sense for all `CartoonCharacter` objects. Do-nothing default behavior is expressed by the empty definitions of those functions in the class (see Item 36). Suppose a particular type of cartoon character is a grasshopper, which dances and sings in its own particular way:

    class Grasshopper: public CartoonCharacter {
    public:
      virtual void dance();    // definition is elsewhere
      virtual void sing();     // definition is elsewhere
    };

Now suppose that after implementing the `Grasshopper` class, you decide you also need a class for crickets:

    class Cricket: public CartoonCharacter {
    public:
      virtual void dance();
      virtual void sing();
    };

As you sit down to implement the `Cricket` class, you realize that a lot of the code you wrote for the `Grasshopper` class can be reused. However, it needs to be tweaked a bit here and there to account for the differences in singing and dancing between grasshoppers and crickets. You are suddenly struck by a clever way to reuse your existing code: you'll implement the `Cricket` class in terms of the `Grasshopper` class, and you'll use virtual functions to allow the `Cricket` class to customize `Grasshopper` behavior!

You immediately recognize that these twin requirements — an is-implemented-in-terms-of relationship and the ability to redefine virtual functions — mean that `Cricket` will have to privately inherit from `Grasshopper`, but of course a cricket is still a cartoon character, so you redefine `Cricket` to inherit from both `Grasshopper` and `CartoonCharacter`:

    class Cricket: public CartoonCharacter,
                   private Grasshopper {
    public:
      virtual void dance();
      virtual void sing();
    };

You then set out to make the necessary modifications to the `Grasshopper` class. In particular, you need to declare some new virtual functions for `Cricket` to redefine:

    class Grasshopper: public CartoonCharacter {
    public:
      virtual void dance();
      virtual void sing();

    protected:
      virtual void danceCustomization1();
      virtual void danceCustomization2();

      virtual void singCustomization();
    };

Dancing for grasshoppers is now defined like this:

    void Grasshopper::dance()
    {
      perform common dancing actions;

      danceCustomization1();

      perform more common dancing actions;

      danceCustomization2();

      perform final common dancing actions;
    }

Grasshopper singing is similarly orchestrated.

Clearly, the `Cricket` class must be updated to take into account the new virtual functions it must redefine:

    class Cricket:public CartoonCharacter,
          private Grasshopper {
    public:
      virtual void dance() { Grasshopper::dance(); }
      virtual void sing() { Grasshopper::sing(); }

    protected:
      virtual void danceCustomization1();
      virtual void danceCustomization2();

      virtual void singCustomization();
    };

This seems to work fine. When a `Cricket` object is told to dance, it will execute the common `dance` code in the `Grasshopper` class, then execute the `dance` customization code in the `Cricket` class, then continue with the code in `Grasshopper::dance`, etc.

There is a serious flaw in your design, however, and that is that you have run headlong into Occam's razor, a bad idea with a razor of any kind, and especially so when it belongs to William of Occam. Occamism preaches that entities should not be multiplied beyond necessity, and in this case, the entities in question are inheritance relationships. If you believe that multiple inheritance is more complicated than single inheritance (and I hope that you do), then the design of the `Cricket` class is needlessly complex.

Fundamentally, the problem is that it is not true that the `Cricket` class is-implemented-in-terms-of the `Grasshopper` class. Rather, the `Cricket` class and the `Grasshopper` class share common code. In particular, they share the code that determines the dancing and singing behavior that grasshoppers and crickets have in common.

The way to say that two classes have something in common is not to have one class inherit from the other, but to have both of them inherit from a common base class. The common code for grasshoppers and crickets doesn't belong in the `Grasshopper` class, nor does it belong in the `Cricket` class. It belongs in a new class from which they both inherit, say, `Insect`:

    class CartoonCharacter { ... };

    class Insect: public CartoonCharacter {
    public:
      virtual void dance();    // common code for both
      virtual void sing();     // grasshoppers and crickets

    protected:
      virtual void danceCustomization1() = 0;
      virtual void danceCustomization2() = 0;

      virtual void singCustomization() = 0;
    };

    class Grasshopper: public Insect {
    protected:
      virtual void danceCustomization1();
      virtual void danceCustomization2();

      virtual void singCustomization();
    };

    class Cricket: public Insect {
    protected:
      virtual void danceCustomization1();
      virtual void danceCustomization2();

      virtual void singCustomization();
    };

Notice how much cleaner this design is. Only single inheritance is involved, and furthermore, only public inheritance is used. `Grasshopper` and `Cricket` define only customization functions; they inherit the `dance` and `sing` functions unchanged from `Insect`. William of Occam would be proud.

Although this design is cleaner than the one involving MI, it may initially have appeared to be inferior. After all, compared to the MI approach, this single-inheritance architecture calls for the introduction of a brand new class, a class unnecessary if MI is used. Why introduce an extra class if you don't have to?

This brings you face to face with the seductive nature of multiple inheritance. On the surface, MI seems to be the easier course of action. It adds no new classes, and though it calls for the addition of some new virtual functions to the `Grasshopper` class, those functions have to be added somewhere in any case.

Imagine now a programmer maintaining a large C++ class library, one in which a new class has to be added, much as the `Cricket` class had to be added to the existing `CartoonCharacter`/`Grasshopper` hierarchy. The programmer knows that a large number of clients use the existing hierarchy, so the bigger the change to the library, the greater the disruption to clients. The programmer is determined to minimize that kind of disruption. Mulling over the options, the programmer realizes that if a single private inheritance link from `Grasshopper` to `Cricket` is added, no other change to the hierarchy will be needed. The programmer smiles at the thought, pleased with the prospect of a large increase in functionality at the cost of only a slight increase in complexity.

Imagine now that that maintenance programmer is you. Resist the seduction.

Back to Item 42: Use private inheritance judiciously.
Continue to Item 44: Say what you mean; understand what you're saying.