📄 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://www.mcp.com/814147200/0-672/0-672-31070-8/htm/ch14rv2.htm"><IMG SRC="BLANPREV.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANPREV.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="tppmsgs/msgs0.htm#1" tppabs="http://www.mcp.com/sams"><IMGSRC="BLANHOME.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANHOME.GIF" WIDTH="37" HEIGHT="37" ALIGN="BOTTOM"BORDER="0"></A><A HREF="index.htm" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/index.htm"><IMG SRC="BLANTOC.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANTOC.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="ch16.htm" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/htm/ch16.htm"><IMG SRC="BLANNEXT.GIF" tppabs="http://www.mcp.com/814147200/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 aclass to include objects of another class. C++ programmers say that the outer classcontains 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 andso 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 withlater listings.</P><P><A NAME="Heading4"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 15.1. The Stringclass.</B></FONT><PRE><FONT COLOR="#0066FF">1: #include <iostream.h>2: #include <string.h>3:4: class String5: {6: public:7: // constructors8: String();9: String(const char *const);10: String(const String &);11: ~String();12:13: // overloaded operators14: 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 accessors21: int GetLen()const { return itsLen; }22: const char * GetString() const { return itsString; }23: // static int ConstructorCount;24:25: private:26: String (int); // private constructor27: char * itsString;28: unsigned short itsLen;29:30: };31:32: // default constructor creates string of 0 bytes33: 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 by43: // class methods for creating a new string of44: // 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 String56: 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 constructor68: 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 memory80: String::~String ()81: {82: delete [] itsString;83: itsLen = 0;84: // cout << "\tString destructor\n";85: }86:87: // operator equals, frees existing memory88: // then copies string and size89: 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, returns104: // reference to character so it can be105: // changed!106: char & String::operator[](int offset)107: {108: if (offset > itsLen)109: return itsString[itsLen-1];110: else111: return itsString[offset];112: }113:114: // constant offset operator for use115: // on const objects (see copy constructor!)116: char String::operator[](int offset) const117: {118: if (offset > itsLen)119: return itsString[itsLen-1];120: else121: return itsString[offset];122: }123:124: // creates a new string by adding current125: // string to rhs126: 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 nothing140: 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." Thesignificant difference here is that the constructors and a few other functions inListing 11.14 have print statements to show their use, which are currently commentedout 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 Employeeclass and driver program.</B></FONT><FONT SIZE="4" COLOR="#0066FF"><B></B></FONT><PRE><FONT COLOR="#0066FF">1: class Employee2: {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;66: }67:68: int main()69: {70: Employee Edie("Jane","Doe","1461 Shore Parkway", 20000);71: Edie.SetSalary(50000);72: String LastName("Levine");73: Edie.SetLastName(LastName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -