Professional C__ - Marc Gregoire [106]
SUMMARY
This chapter, along with Chapter 6, provided all the tools you need to write solid, well-designed classes, and to use objects effectively.
You discovered that dynamic memory allocation in objects presents new challenges: You must free the memory in the destructor, copy the memory in the copy constructor, and both free and copy the memory in the assignment operator. You learned how to prevent assignment and pass-by-value by declaring a private copy constructor and assignment operator.
You learned more about different kinds of data members, including static, const, const reference, and mutable members. You also learned about static, inline, and const methods, method overloading and default parameters. The chapter also described nested class definitions, and friend classes, functions and methods.
You encountered operator overloading, and learned how to overload the arithmetic and comparison operators, both as global friend functions and as class methods.
Finally, you learned how to take abstraction to an extreme by providing separate interface and implementation classes.
Now that you’re fluent in the language of object-oriented programming, it’s time to tackle inheritance, which is covered in Chapter 8.
Chapter 8
Discovering Inheritance Techniques
WHAT’S IN THIS CHAPTER?
How to extend a class through inheritance
How to employ inheritance to reuse code
How to build interactions between superclasses and subclasses
How to use inheritance to achieve polymorphism
How to work with multiple inheritance
How to deal with unusual problems in inheritance
Without inheritance, classes would simply be data structures with associated behaviors. That alone would be a powerful improvement over procedural languages, but inheritance adds an entirely new dimension. Through inheritance, you can build new classes based on existing ones. In this way, your classes become reusable and extensible components. This chapter will teach you the different ways to leverage the power of inheritance. You will learn about the specific syntax of inheritance as well as sophisticated techniques for making the most of inheritance.
The portion of this chapter relating to polymorphism draws heavily on the spreadsheet example discussed in Chapters 6 and 7. If you have not read Chapters 6 and 7, you may wish to skim the sample code in those chapters to get a background on this example. This chapter also refers to the object-oriented methodologies described in Chapter 3. If you have not read that chapter and are unfamiliar with the theories behind inheritance, you should review Chapter 3 before continuing.
BUILDING CLASSES WITH INHERITANCE
In Chapter 3, you learned that an “is-a” relationship recognizes the pattern that real-world objects tend to exist in hierarchies. In programming, that pattern becomes relevant when you need to write a class that builds on, or slightly changes, another class. One way to accomplish this aim is to copy code from one class and paste it into the other. By changing the relevant parts or amending the code, you can achieve the goal of creating a new class that is slightly different from the original. This approach, however, leaves an OOP programmer feeling sullen and slightly annoyed for the following reasons:
A bug fix to the original class will not be reflected in the new class because the two classes contain completely separate code.
The compiler does not know about any relationship between the two classes, so they are not polymorphic — they are not just different variations on the same thing.
This approach does not build a true is-a relationship. The new class is very similar to the original because it shares code, not because it really is the same type of object.
The original code might not be obtainable. It may exist only in a precompiled binary format, so copying and pasting the code might be impossible.
Not surprisingly, C++ provides built-in support for defining a true is-a relationship. The characteristics of C++ is-a