Online Book Reader

Home Category

Professional C__ - Marc Gregoire [120]

By Root 1523 0

As long as the compiler has a way to turn a particular cell into a StringSpreadsheetCell, the operator will work. Given the previous example of having a StringSpreadsheetCell constructor that takes a DoubleSpreadsheetCell as an argument, the compiler will automatically perform the conversion if it is the only way to get the operator+ to work. That means the following code will work, even though operator+ was explicitly written to work on StringSpreadsheetCells:

DoubleSpreadsheetCell myDbl;

myDbl.set(8.4);

StringSpreadsheetCell result = myDbl + myDbl;

Code snippet from PolymorphicSpreadsheet\SpreadsheetTest.cpp

Of course, the result of this addition won’t really add the numbers together. It will convert the double cells into string cells and add the strings, resulting in a StringSpreadsheetCell with a value of 8.48.4.

If you are still feeling a little unsure about polymorphism, start with the code for this example and try things out. The main() function in the preceding example is a great starting point for experimental code that simply exercises various aspects of the class.

MULTIPLE INHERITANCE


As you read in Chapter 3, multiple inheritance is often perceived as a complicated and unnecessary part of object-oriented programming. We’ll leave the decision of whether or not it is useful up to you and your coworkers. This section explains the mechanics of multiple inheritance in C++.

Inheriting from Multiple Classes

Defining a class to have multiple parent classes is very simple from a syntactic point of view. All you need to do is list the superclasses individually when declaring the class name.

class Baz : public Foo, public Bar

{

// Etc.

};

By listing multiple parents, the Baz object will have the following characteristics:

A Baz object will support the public methods and contain the data members of both Foo and Bar.

The methods of the Baz class will have access to protected data and methods in both Foo and Bar.

A Baz object can be upcast to either a Foo or a Bar.

Creating a new Baz object will automatically call the Foo and Bar default constructors, in the order that the classes were listed in the class definition.

Deleting a Baz object will automatically call the destructors for the Foo and Bar classes, in the reverse order that the classes were listed in the class definition.

The following example shows a class, DogBird, that has two parent classes — a Dog class and a Bird class. The fact that a dog-bird is a ridiculous example should not be viewed as a statement that multiple inheritance itself is ridiculous. Honestly, we leave that judgment up to you.

class Dog

{

public:

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

};

class Bird

{

public:

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

};

class DogBird : public Dog, public Bird

{

};

Code snippet from DogBird\DogBird.cpp

The class hierarchy for DogBird is shown in Figure 8-7.

FIGURE 8-7

Using objects of classes with multiple parents is no different from using objects without multiple parents. In fact, the client code doesn’t even have to know that the class has two parents. All that really matters are the properties and behaviors supported by the class. In this case, a DogBird object supports all of the public methods of Dog and Bird.

DogBird myConfusedAnimal;

myConfusedAnimal.bark();

myConfusedAnimal.chirp();

Code snippet from DogBird\DogBird.cpp

The output of this program is as follows:

Woof!

Chirp!

Naming Collisions and Ambiguous Base Classes

It’s not difficult to construct a scenario where multiple inheritance would seem to break down. The following examples show some of the edge cases that must be considered:

Name Ambiguity

What if the Dog class and the Bird class both had a method called eat()? Since Dog and Bird are not related in any way, one version of the method does not override the other — they both continue to exist in the DogBird subclass.

As long as client code never attempts to call the eat() method, that is not a problem. The DogBird class will compile correctly despite having

Return Main Page Previous Page Next Page

®Online Book Reader