Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

C++ in Plain English
(Publisher: IDG Books Worldwide, Inc.)
Author(s): Brian Overland
ISBN: 1558284729
Publication Date: 04/01/96

Bookmark It

Search this book:
 
Previous Table of Contents Next


Chapter 8
Inheritance: C++ and Good Genes

Inheritance is all about software reuse, C++’s greatest promise. Never write the same piece of code twice! Make exponential gains in productivity! Of course, it’s not quite that easy. But if you’re thinking about reusable components, inheritance provides a convenient, time-saving way of packaging them.

Beyond that, inheritance provides the underlying structure for virtual functions. I’ll talk about virtual functions in the next chapter.

As much as any C++ buzzword, inheritance seems to metaphorically endow objects with life. After all, isn’t inheritance a property of living things? That would be going too far, but inheritance, as you’ll see, does allow you to develop a useful hierarchy that goes from the general to the specific—much like a deity or Darwin (take your pick).

Return to CStr: A Software Dilemma

If you’ve been reading the chapters of this book sequentially, you know about the CStr class and how to write it. Let’s assume for a moment, though, that someone else developed the CStr class and then sold you the right to use the software. Typically, here’s what you are provided with:

  A header file containing the class declaration.
  An object-file (.OBJ file) containing the implementations of member functions of the class in compiled form.

The second item includes implementations of all functions except those defined in the class declaration. The latter are inline functions.

Most of the source code is not available. The provider or vendor of a class is under no obligation to provide the C++ code beyond the class declaration. There are often good reasons for not providing the source code for functions. Vendors may not wish others to see all the details of their programming techniques.

All this is fine as long as the class does exactly what you want it to do. But suppose you want to modify or add to some aspect of the class behavior. What do you do with the CStr class? Must you limit yourself to the behavior of the class or write your own CStr class from scratch? Fortunately, better alternatives are available. One alternative is to create a class that contains a CStr object as a member; in such an approach you’re essentially building an outer class around the CStr class.

But a better alternative, in light of the amount of work required, is to use inheritance. This means creating a new class and deriving it from CStr. In deriving one class from another, you include all the members of the first class (called the base class) and then add more members. Another term for this is inheriting from the base class.

Ultimately, deriving a class has an effect similar to building one class around another: you get all the built-in functionality and add your own. The effect is about the same, but the inheritance syntax potentially saves you a great deal of work.

Son of CStr (Or Is It “Daughter”?)

The final version of the CStr class—summarized in Chapter 7, “Class Operations ”— supported a number of useful functions and operations, including those shown in Table 8.1.

Table 8.1 Functions and operations of the CStr class.
Function or Operation Description
get Return pointer to null-terminated string data.
getlength Return length of string data.
cpy Copy string from char* argument.
cat Concatenate char* argument onto current string data.
+ Concatenate two strings, of which at least one is a CStr object. The other may be a CStr object or a char*
= Copy string data from another CStr object.

The class also supports a number of useful constructors. Let’s assume that you’d like to retain all this functionality as well as add the following:

  output, which would print string data to standard output.
  input, which would input a string from standard input.

Deriving a class through inheritance makes it easy to add this functionality without access to the original CStr code and without having to rewrite any of the CStr class. The next section introduces the syntax.

Derived Class Syntax

Assume that a class Parent_class has already been declared. The following syntax derives Class_class from Parent_class; this means that Child_class has all the members defined in Parent_class in addition to any declarations of its own.

class Child_class:public Parent_class {
           declarations
};

The only part that is new here is the colon {:} and the syntax that follows:

public Parent_class

In this context, public is the base-class access specifier. Alternatively, you can specify either private or protected. In the majority of cases, public suffices. For information about the effect of the other keywords, see the topic “Base-Class Access” in Part II.

The declarations for Child_class include the new members to be added to the declarations in Parent_class. For example, the following declaration creates CStr as a class derived from CStr. CIoStr contains all the CStr members in addition to the member functions input and output.

// CIOSTR.H — declaration of the CIOStr class

#include “cstr.h”

class CIoStr : public CStr {
public:
    void input(void);
    void output(void);
};

Note that the file CSTR.H is included, which results in CStr being declared before CIoStr. A class must be declared before you can derive another class from it.

Given this declaration of the CIoStr class, you can use CIoStr to declare objects just as you can with CStr. These objects support two new functions—input and output—in addition to all the functions supported by a CStr object. For example:

CIoStr iostring1, iostring2, iostring3;

iostring1 = “This is a new string”;
iostring2 = iostring1 + “.”;
iostring2.output();
iostring1.input();
iostring3.cpy(iostring1);

Writing Functions for the New Class

CIoStr follows the same rules that any class follows for implementing member functions: for each member function, you can either define the function inside the class declaration (in which case it is automatically an inline function), or you can define the function outside the declaration. In the latter case, you use CIoStr:: to prefix the name.


Previous Table of Contents Next
[an error occurred while processing this directive]

Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.