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


In addition to these functions, a complete implementation would also include the operator and conversion functions for the CStr class.

Now compare the version of CIoStr you’ve just seen to the earlier one:

#include “cstr.h”>

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

The effect is the same with either approach: the CIoStr class supports all the same member functions that CStr does and then adds two new functions (input and output). Clearly, the version that uses inheritance has a much simpler, cleaner, and more elegant syntax.

In theory, you can think of inheritance and object containment —declaring one object inside another—as being different. Inheritance, according to object-oriented theory, should be used in situations of the form “A is a kind of B.” A, the derived class, is simply a more specialized version of B, the base class. Adopting this approach, we would say that CIoStr is a more specialized kind of string than CStr, and therefore it adds new functions. But both are strings.

With object containment, on the other hand, one class uses—or is a client of—the other class. For example, you might create a CAddress class that contains several strings (CStr objects), among other data.

class CAddress {
   CStr name;
   CStr line1;
   CStr line2;
   int months_at_residence;
};

You wouldn’t consider CAddress to be simply a more specialized type of string; it is a fundamentally different type from CStr.

These cases are fairly clear-cut. But in some cases it can be more difficult to decide whether one class should be derived from another (inheritance) or whether one class should contain the other. The best policy is to remember that inheritance is a convenient bit of syntax for including all the members of one class in another and is therefore not very different from containment. (Inheritance also has a critical role in virtual functions, a fact we’ll look at in the next chapter.)

Another way to simulate inheritance, by the way, is to use object containment but rely on the user of the object to adjust function calls.

#include “cstr.h”

class CIoStr : public CStr {
public:
   CStr str;

   void input(void);
   void output(void);
};

It’s easy to write this class, but it’s not as convenient to use. Most functions have to be called through the data member str. For example, the following code fragment calls the cpy function:

CIoStr Iostring;
. . .
iostring.str.cpy(“Let’s go to the Oscars.”);

If you had used inheritance, the call to cpy would be made more directly. The moral of the story is that in situations such as this one, inheritance can often be more convenient than other techniques.

Public, Private, and Protected Access

So far I have introduced one member-access keyword: public. In certain respects, this keyword is the most useful. But C++ has three member-access keywords: public, private, and protected.

Within class declarations, private is the default member access level. Because it is the default, you can usually get away with not using it. However, making private access explicit is a good idea because it makes the class declarations easier to read. For example, here is the CFontIoStr declaration with the private keyword used to clarify the access level of ptsize:

#include “CIoStr.h”

class CFontIoStr : public CIoStr {
private:

   int ptsize;
public:
   void clr(void) {cpy(“ ”); }
   void setchar(int c, int n);
   void set_font(int size);
};

The third access level, protected, is an intermediate level between private and public. A member with protected access can be accessed with the scope of the class and its derived classes but is private in any other scope.

Look at the CIoStr declaration again. This class inherits from CStr, the original class, and adds two new functions.

#include “cstr.h”

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

In the declaration of CStr, the two data members (pData and nLength) were declared private. This was done by default, because they were not declared with the public keyword. This is fine unless you want the new functions in CIoStr to be able to refer to the data members. At that point, there is a problem:

void CIoStr::print(void) {
   printf(“%s”, pData);   //ERROR! No access to pData
}

Earlier, I said that a derived class inherits all the members of its base class. This is true, even here. The data member pData is present in every instance of CIoStr and can be accessed indirectly through a CStr member function such as get or cpy. However, pData is not visible in function definitions for the derived class CIoStr.

If pData and nLength had been declared with the protected keyword in the CStr declaration, then they could be accessed in CStr function definitions and in CIoStr function definitions.

class CStr {
protected:
    char *pData;
    int nLength;
public:
    Cstr();          //Constructors
    CStr(char *s);
    CStr(const CStr &str);
    ~CStr();        // Destructor
. . .

Figure 8.3 summarizes the three levels of member-access rights—public, protected, and private.


Figure 8.3  Member-access levels summarized.

Is it better to declare data members as protected or as private? The answer depends on the purpose of the members. In the case of the CStr class, it probably isn’t necessary to declare pData and nLength as protected, because a series of public functions—get, getlength, cpy, and cat—provide complete access to the data.


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.