?? ch15.htm
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<!-- This document was created from RTF source by rtftohtml version 3.0.1 -->
<META NAME="GENERATOR" Content="Symantec Visual Page 1.0">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<TITLE>Teach Yourself C++ in 21 Days</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF">
<H1 ALIGN="CENTER"><A HREF="ch14rv2.htm" tppabs="http://petunia.atomki.hu/pio/Manuals/english/0-672/0-672-31070-8/htm/ch14rv2.htm"><IMG SRC="../buttons/BLANPREV.GIF" tppabs="http://petunia.atomki.hu/pio/Manuals/english/0-672/0-672-31070-8/buttons/BLANPREV.GIF"
WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="javascript:if(confirm('http://www.mcp.com/sams \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.mcp.com/sams'" tppabs="http://www.mcp.com/sams"><IMG
SRC="../buttons/BLANHOME.GIF" tppabs="http://petunia.atomki.hu/pio/Manuals/english/0-672/0-672-31070-8/buttons/BLANHOME.GIF" WIDTH="37" HEIGHT="37" ALIGN="BOTTOM"
BORDER="0"></A><A HREF="../index.htm" tppabs="http://petunia.atomki.hu/pio/Manuals/english/0-672/0-672-31070-8/index.htm"><IMG SRC="../buttons/BLANTOC.GIF" tppabs="http://petunia.atomki.hu/pio/Manuals/english/0-672/0-672-31070-8/buttons/BLANTOC.GIF"
WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="ch16.htm" tppabs="http://petunia.atomki.hu/pio/Manuals/english/0-672/0-672-31070-8/htm/ch16.htm"><IMG SRC="../buttons/BLANNEXT.GIF" tppabs="http://petunia.atomki.hu/pio/Manuals/english/0-672/0-672-31070-8/buttons/BLANNEXT.GIF"
WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A></H1>
<H1></H1>
<UL>
<LI><A HREF="#Heading1">Day 15</A>
<UL>
<LI><A HREF="#Heading2">Advanced Inheritance</A>
<UL>
<LI><A HREF="#Heading3">Containment</A>
<LI><A HREF="#Heading4">Listing 15.1. The String class</A><A HREF="#Heading5">.</A>
<LI><A HREF="#Heading6">Listing 15.2. The Employee class and driver program</A><A
HREF="#Heading7">.</A>
<UL>
<LI><A HREF="#Heading8">Accessing Members of the Contained Class</A>
<LI><A HREF="#Heading9">Filtering Access to Contained Members</A>
<LI><A HREF="#Heading10">Cost of Containment</A>
</UL>
<LI><A HREF="#Heading11">Listing 15.3. Contained class constructors</A><A HREF="#Heading12">.</A>
<UL>
<LI><A HREF="#Heading13">Copying by Value</A>
</UL>
<LI><A HREF="#Heading14">Listing 15.4. Passing by value</A><A HREF="#Heading15">.</A>
<LI><A HREF="#Heading16">Implementation in Terms of Inheritance/Containment Versus
Delegation</A>
<UL>
<LI><A HREF="#Heading17">Delegation</A>
</UL>
<LI><A HREF="#Heading18">Listing 15.5. Delegating to a contained LinkedList</A><A
HREF="#Heading19">.</A>
<LI><A HREF="#Heading20">Private Inheritance</A>
<LI><A HREF="#Heading21">Listing 15.6. Private</A>
<LI><A HREF="#Heading22">inheritance</A><A HREF="#Heading23">.</A>
<LI><A HREF="#Heading24">Friend Classes</A>
<LI><A HREF="#Heading25">Listing 15.7. Friend class illustrated</A><A HREF="#Heading26">.</A>
<LI><A HREF="#Heading27">Friend Class</A>
<LI><A HREF="#Heading28">Friend Functions</A>
<LI><A HREF="#Heading29">Friend Functions and Operator Overloading</A>
<LI><A HREF="#Heading30">Listing 15.8. Friendly operator+.</A>
<LI><A HREF="#Heading31">Friend Functions</A>
<LI><A HREF="#Heading32">Overloading the Insertion Operator</A>
<LI><A HREF="#Heading33">Listing 15.9. Overloading operator<<().</A>
<LI><A HREF="#Heading34">Summary</A>
<LI><A HREF="#Heading35">Q&A</A>
<LI><A HREF="#Heading36">Workshop</A>
<UL>
<LI><A HREF="#Heading37">Quiz</A>
<LI><A HREF="#Heading38">Exercises</A>
</UL>
</UL>
</UL>
</UL>
<P>
<HR SIZE="4">
<H2 ALIGN="CENTER"><A NAME="Heading1"></A><FONT COLOR="#000077">Day 15</FONT></H2>
<H2 ALIGN="CENTER"><A NAME="Heading2"></A><FONT COLOR="#000077">Advanced Inheritance</FONT></H2>
<P>So far you have worked with single and multiple inheritance to create is-a relationships.
Today you will learn
<UL>
<LI>What containment is and how to model it.
<P>
<LI>What delegation is and how to model it.
<P>
<LI>How to implement one class in terms of another.
<P>
<LI>How to use private inheritance.
</UL>
<H3 ALIGN="CENTER"><A NAME="Heading3"></A><FONT COLOR="#000077">Containment</FONT></H3>
<P>As you have seen in previous examples, it is possible for the member data of a
class to include objects of another class. C++ programmers say that the outer class
contains the inner class. Thus, an <TT>Employee</TT> class might contain string objects
(for the name of the employee), as well as integers (for the employee's salary and
so forth).</P>
<P>Listing 15.1 describes an incomplete, but still useful, <TT>String</TT> class.
This listing does not produce any output. Instead Listing 15.1 will be used with
later listings.</P>
<P><A NAME="Heading4"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 15.1. The String
class.</B></FONT>
<PRE><FONT COLOR="#0066FF">1: #include <iostream.h>
2: #include <string.h>
3:
4: class String
5: {
6: public:
7: // constructors
8: String();
9: String(const char *const);
10: String(const String &);
11: ~String();
12:
13: // overloaded operators
14: char & operator[](int offset);
15: char operator[](int offset) const;
16: String operator+(const String&);
17: void operator+=(const String&);
18: String & operator= (const String &);
19:
20: // General accessors
21: int GetLen()const { return itsLen; }
22: const char * GetString() const { return itsString; }
23: // static int ConstructorCount;
24:
25: private:
26: String (int); // private constructor
27: char * itsString;
28: unsigned short itsLen;
29:
30: };
31:
32: // default constructor creates string of 0 bytes
33: String::String()
34: {
35: itsString = new char[1];
36: itsString[0] = `\0';
37: itsLen=0;
38: // cout << "\tDefault string constructor\n";
39: // ConstructorCount++;
40: }
41:
42: // private (helper) constructor, used only by
43: // class methods for creating a new string of
44: // required size. Null filled.
45: String::String(int len)
46: {
47: itsString = new char[len+1];
48: for (int i = 0; i<=len; i++)
49: itsString[i] = `\0';
50: itsLen=len;
51: // cout << "\tString(int) constructor\n";
52: // ConstructorCount++;
53: }
54:
55: // Converts a character array to a String
56: String::String(const char * const cString)
57: {
58: itsLen = strlen(cString);
59: itsString = new char[itsLen+1];
60: for (int i = 0; i<itsLen; i++)
61: itsString[i] = cString[i];
62: itsString[itsLen]='\0';
63: // cout << "\tString(char*) constructor\n";
64: // ConstructorCount++;
65: }
66:
67: // copy constructor
68: String::String (const String & rhs)
69: {
70: itsLen=rhs.GetLen();
71: itsString = new char[itsLen+1];
72: for (int i = 0; i<itsLen;i++)
73: itsString[i] = rhs[i];
74: itsString[itsLen] = `\0';
75: // cout << "\tString(String&) constructor\n";
76: // ConstructorCount++;
77: }
78:
79: // destructor, frees allocated memory
80: String::~String ()
81: {
82: delete [] itsString;
83: itsLen = 0;
84: // cout << "\tString destructor\n";
85: }
86:
87: // operator equals, frees existing memory
88: // then copies string and size
89: String& String::operator=(const String & rhs)
90: {
91: if (this == &rhs)
92: return *this;
93: delete [] itsString;
94: itsLen=rhs.GetLen();
95: itsString = new char[itsLen+1];
96: for (int i = 0; i<itsLen;i++)
97: itsString[i] = rhs[i];
98: itsString[itsLen] = `\0';
99: return *this;
100: // cout << "\tString operator=\n";
101: }
102:
103: //non constant offset operator, returns
104: // reference to character so it can be
105: // changed!
106: char & String::operator[](int offset)
107: {
108: if (offset > itsLen)
109: return itsString[itsLen-1];
110: else
111: return itsString[offset];
112: }
113:
114: // constant offset operator for use
115: // on const objects (see copy constructor!)
116: char String::operator[](int offset) const
117: {
118: if (offset > itsLen)
119: return itsString[itsLen-1];
120: else
121: return itsString[offset];
122: }
123:
124: // creates a new string by adding current
125: // string to rhs
126: String String::operator+(const String& rhs)
127: {
128: int totalLen = itsLen + rhs.GetLen();
129: String temp(totalLen);
130: int i, j;
131: for (i = 0; i<itsLen; i++)
132: temp[i] = itsString[i];
133: for (j = 0; j<rhs.GetLen(); j++, i++)
134: temp[i] = rhs[j];
135: temp[totalLen]='\0';
136: return temp;
137: }
138:
139: // changes current string, returns nothing
140: void String::operator+=(const String& rhs)
141: {
142: unsigned short rhsLen = rhs.GetLen();
143: unsigned short totalLen = itsLen + rhsLen;
144: String temp(totalLen);
145: for (int i = 0; i<itsLen; i++)
146: temp[i] = itsString[i];
147: for (int j = 0; j<rhs.GetLen(); j++, i++)
148: temp[i] = rhs[i-itsLen];
149: temp[totalLen]='\0';
150: *this = temp;
151: }
152:
<TT>153: // int String::ConstructorCount = 0;</TT></FONT></PRE>
<P><TT><BR>
</TT><B>Output: </B>None.</P>
<P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>Listing 15.1 provides a <TT>String</TT>
class much like the one used in Listing 11.14 of Day 11, "Arrays." The
significant difference here is that the constructors and a few other functions in
Listing 11.14 have print statements to show their use, which are currently commented
out in Listing 15.1. These functions will be used in later examples.</P>
<P>On line 23, the static member variable <TT>ConstructorCount</TT> is declared,
and on line 153 it is initialized. This variable is incremented in each string constructor.
All of this is currently commented out; it will be used in a later listing.</P>
<P>Listing 15.2 describes an <TT>Employee</TT> class that contains three string objects.
Note that a number of statements are commented out; they will be used in later listings.</P>
<P><A NAME="Heading6"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 15.2. The Employee
class and driver program.</B></FONT><FONT SIZE="4" COLOR="#0066FF"><B></B></FONT>
<PRE><FONT COLOR="#0066FF">1: class Employee
2: {
3:
4: public:
5: Employee();
6: Employee(char *, char *, char *, long);
7: ~Employee();
8: Employee(const Employee&);
9: Employee & operator= (const Employee &);
10:
11: const String & GetFirstName() const
12: { return itsFirstName; }
13: const String & GetLastName() const { return itsLastName; }
14: const String & GetAddress() const { return itsAddress; }
15: long GetSalary() const { return itsSalary; }
16:
17: void SetFirstName(const String & fName)
18: { itsFirstName = fName; }
19: void SetLastName(const String & lName)
20: { itsLastName = lName; }
21: void SetAddress(const String & address)
22: { itsAddress = address; }
23: void SetSalary(long salary) { itsSalary = salary; }
24: private:
25: String itsFirstName;
26: String itsLastName;
27: String itsAddress;
28: long itsSalary;
29: };
30:
31: Employee::Employee():
32: itsFirstName(""),
33: itsLastName(""),
34: itsAddress(""),
35: itsSalary(0)
36: {}
37:
38: Employee::Employee(char * firstName, char * lastName,
39: char * address, long salary):
40: itsFirstName(firstName),
41: itsLastName(lastName),
42: itsAddress(address),
43: itsSalary(salary)
44: {}
45:
46: Employee::Employee(const Employee & rhs):
47: itsFirstName(rhs.GetFirstName()),
48: itsLastName(rhs.GetLastName()),
49: itsAddress(rhs.GetAddress()),
50: itsSalary(rhs.GetSalary())
51: {}
52:
53: Employee::~Employee() {}
54:
55: Employee & Employee::operator= (const Employee & rhs)
56: {
57: if (this == &rhs)
58: return *this;
59:
60: itsFirstName = rhs.GetFirstName();
61: itsLastName = rhs.GetLastName();
62: itsAddress = rhs.GetAddress();
63: itsSalary = rhs.GetSalary();
64:
65: return *this;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -