⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch11.htm

📁 一本好的VC学习书,本人就是使用这本书开始学习的vc,希望能对大家有帮助
💻 HTM
📖 第 1 页 / 共 5 页
字号:
61:62:    // copy constructor63:    String::String (const String &amp; rhs)64:    {65:       itsLen=rhs.GetLen();66:       itsString = new char[itsLen+1];67:       for (unsigned short i = 0; i&lt;itsLen;i++)68:          itsString[i] = rhs[i];69:       itsString[itsLen] = `\0';70:    }71:72:    // destructor, frees allocated memory73:    String::~String ()74:    {75:       delete [] itsString;76:       itsLen = 0;77:    }78:79:    // operator equals, frees existing memory80:    // then copies string and size81:    String&amp; String::operator=(const String &amp; rhs)82:    {83:       if (this == &amp;rhs)84:          return *this;85:       delete [] itsString;86:       itsLen=rhs.GetLen();87:       itsString = new char[itsLen+1];88:       for (unsigned short i = 0; i&lt;itsLen;i++)89:          itsString[i] = rhs[i];90:       itsString[itsLen] = `\0';91:       return *this;92:    }93:94:    //nonconstant offset operator, returns95:    // reference to character so it can be96:    // changed!97:    char &amp; String::operator[](unsigned short offset)98:    {99:       if (offset &gt; itsLen)100:         return itsString[itsLen-1];101:      else102:         return itsString[offset];103:   }104:105:   // constant offset operator for use106:   // on const objects (see copy constructor!)107:   char String::operator[](unsigned short offset) const108:   {109:      if (offset &gt; itsLen)110:         return itsString[itsLen-1];111:      else112:         return itsString[offset];113:   }114:115:   // creates a new string by adding current116:   // string to rhs117:   String String::operator+(const String&amp; rhs)118:   {119:      unsigned short  totalLen = itsLen + rhs.GetLen();120:      String temp(totalLen);121:      for (unsigned short i = 0; i&lt;itsLen; i++)122:         temp[i] = itsString[i];123:      for (unsigned short j = 0; j&lt;rhs.GetLen(); j++, i++)124:         temp[i] = rhs[j];125:      temp[totalLen]='\0';126:      return temp;127:   }128:129:   // changes current string, returns nothing130:   void String::operator+=(const String&amp; rhs)131:   {132:      unsigned short rhsLen = rhs.GetLen();133:      unsigned short totalLen = itsLen + rhsLen;134:      String  temp(totalLen);135:      for (unsigned short i = 0; i&lt;itsLen; i++)136:         temp[i] = itsString[i];137:      for (unsigned short j = 0; j&lt;rhs.GetLen(); j++, i++)138:         temp[i] = rhs[i-itsLen];139:      temp[totalLen]='\0';140:      *this = temp;141:   }142:143:   int main()144:   {145:      String s1(&quot;initial test&quot;);146:      cout &lt;&lt; &quot;S1:\t&quot; &lt;&lt; s1.GetString() &lt;&lt; endl;147:148:      char * temp = &quot;Hello World&quot;;149:      s1 = temp;150:      cout &lt;&lt; &quot;S1:\t&quot; &lt;&lt; s1.GetString() &lt;&lt; endl;151:152:      char tempTwo[20];153:      strcpy(tempTwo,&quot;; nice to be here!&quot;);154:      s1 += tempTwo;155:      cout &lt;&lt; &quot;tempTwo:\t&quot; &lt;&lt; tempTwo &lt;&lt; endl;156:      cout &lt;&lt; &quot;S1:\t&quot; &lt;&lt; s1.GetString() &lt;&lt; endl;157:158:      cout &lt;&lt; &quot;S1[4]:\t&quot; &lt;&lt; s1[4] &lt;&lt; endl;159:      s1[4]='x';160:      cout &lt;&lt; &quot;S1:\t&quot; &lt;&lt; s1.GetString() &lt;&lt; endl;161:162:      cout &lt;&lt; &quot;S1[999]:\t&quot; &lt;&lt; s1[999] &lt;&lt; endl;163:164:      String s2(&quot; Another string&quot;);165:      String s3;166:      s3 = s1+s2;167:      cout &lt;&lt; &quot;S3:\t&quot; &lt;&lt; s3.GetString() &lt;&lt; endl;168:169:      String s4;170:      s4 = &quot;Why does this work?&quot;;171:      cout &lt;&lt; &quot;S4:\t&quot; &lt;&lt; s4.GetString() &lt;&lt; endl;172:     return 0;<TT>173: }</TT></FONT><FONT COLOR="#0066FF">Output: S1:        initial testS1:        Hello worldtempTwo:           ; nice to be here!S1:        Hello world; nice to be here!S1[4]:     oS1:        Hellx World; nice to be here!S1[999]:           !S3:        Hellx World; nice to be here! Another stringS4:        Why does this work?</FONT></PRE><P><FONT COLOR="#000077"><B><BR>Analysis:</B></FONT><B> </B>Lines 7-31 are the declaration of a simple <TT>String</TT>class. Lines 11-13 contain three constructors: the default constructor, the copyconstructor, and a constructor that takes an existing null-terminated (C-style) string.<BR>This <TT>String</TT> class overloads the offset operator (<TT>[ ]</TT>), operatorplus (<TT>+</TT>), and operator plus-equals (<TT>+=</TT>). The offset operator isoverloaded twice: once as a constant function returning a <TT>char</TT> and againas a nonconstant function returning a reference to a <TT>char</TT>.</P><P>The nonconstant version is used in statements such as</P><PRE><FONT COLOR="#0066FF">SomeString[4]='x';</FONT></PRE><P>as seen in line 159. This enables direct access to each of the characters in thestring. A reference to the character is returned so that the calling function canmanipulate it.</P><P>The constant version is used when a constant <TT>String</TT> object is being accessed,such as in the implementation of the copy constructor, (line 63). Note that <TT>rhs[i]</TT>is accessed, yet <TT>rhs</TT> is declared as a <TT>const String &amp;</TT>. It isn'tlegal to access this object by using a nonconstant member function. Therefore, thereference operator must be overloaded with a constant accessor.</P><P>If the object being returned were large, you might want to declare the returnvalue to be a constant reference. However, because a <TT>char</TT> is only one byte,there would be no point in doing that.</P><P>The default constructor is implemented in lines 33-39. It creates a string whoselength is 0. It is the convention of this <TT>String</TT> class to report its lengthnot counting the terminating null. This default string contains only a terminatingnull.</P><P>The copy constructor is implemented in lines 63-70. It sets the new string's lengthto that of the existing string--plus 1 for the terminating null. It copies each characterfrom the existing string to the new string, and it null-terminates the new string.</P><P>Lines 53-60 implement the constructor that takes an existing C-style string. Thisconstructor is similar to the copy constructor. The length of the existing stringis established by a call to the standard <TT>String</TT> library function <TT>strlen()</TT>.</P><P>On line 28, another constructor, <TT>String(unsigned short)</TT>, is declaredto be a private member function. It is the intent of the designer of this class thatno client class ever create a <TT>String</TT> of arbitrary length. This constructorexists only to help in the internal creation of <TT>String</TT>s as required, forexample, by <TT>operator+=</TT>, on line 130. This will be discussed in depth when<TT>operator+=</TT> is described, below.</P><P>The <TT>String(unsigned short)</TT> constructor fills every member of its arraywith <TT>NULL</TT>. Therefore, the <TT>for</TT> loop checks for <TT>i&lt;=len</TT>rather than <TT>i&lt;len</TT>.</P><P>The destructor, implemented in lines 73-77, deletes the character string maintainedby the class. Be sure to include the brackets in the call to the delete operator,so that every member of the array is deleted, instead of only the first.</P><P>The assignment operator first checks whether the right-hand side of the assignmentis the same as the left-hand side. If it isn't, the current string is deleted, andthe new string is created and copied into place. A reference is returned to facilitateassignments lik</P><PRE><FONT COLOR="#0066FF">String1 = String2 = String3;</FONT></PRE><P>The offset operator is overloaded twice. Rudimentary bounds checking is performedboth times. If the user attempts to access a character at a location beyond the endof the array, the last character--that is, <TT>len-1</TT>--is returned.</P><P>Lines 117-127 implement operator plus (+) as a concatenation operator. It is convenientto be able to write</P><PRE><FONT COLOR="#0066FF">String3 = String1 + String2;</FONT></PRE><P>and have <TT>String3</TT> be the concatenation of the other two strings. To accomplishthis, the operator plus function computes the combined length of the two stringsand creates a temporary string <TT>temp</TT>. This invokes the private constructor,which takes an integer, and creates a string filled with nulls. The nulls are thenreplaced by the contents of the two strings. The left-hand side string (<TT>*this</TT>)is copied first, followed by the right-hand side string (<TT>rhs</TT>).</P><P>The first <TT>for</TT> loop counts through the string on the left-hand side andadds each character to the new string. The second <TT>for</TT> loop counts throughthe right-hand side. Note that <TT>i</TT> continues to count the place for the newstring, even as <TT>j</TT> counts into the <TT>rhs</TT> string.</P><P>Operator plus returns the <TT>temp</TT> string by value, which is assigned tothe string on the left-hand side of the assignment (<TT>string1</TT>). Operator <TT>+=</TT>operates on the existing string--that is, the left-hand side of the statement <TT>string1+= string2</TT>. It works just like operator plus, except that the <TT>temp</TT>value is assigned to the current string (<TT>*this = temp</TT>) in line 140.</P><P>The <TT>main()</TT>function (lines 143-173) acts as a test driver program forthis class. Line 145 creates a <TT>String</TT> object by using the constructor thattakes a null-terminated C-style string. Line 146 prints its contents by using theaccessor function <TT>GetString()</TT>. Line 148 creates another C-style string.Line 149 tests the assignment operator, and line 150 prints the results.</P><P>Line 152 creates a third C-style string, <TT>tempTwo</TT>. Line 153 invokes <TT>strcpy</TT>to fill the buffer with the characters <TT>; nice to be here!</TT> Line 154 invokesoperator <TT>+=</TT> and concatenates <TT>tempTwo</TT> onto the existing string <TT>s1.</TT>Line 156 prints the results.</P><P>In line 158, the fifth character in <TT>s1</TT> is accessed and printed. It isassigned a new value in line 159. This invokes the nonconstant offset operator (<TT>[]</TT>). Line 160 prints the result, which shows that the actual value has, in fact,been changed.</P><P>Line 162 attempts to access a character beyond the end of the array. The lastcharacter of the array is returned, as designed.</P><P>Lines 164-165 create two more <TT>String</TT> objects, and line 166 calls theaddition operator. Line 167 prints the results.</P><P>Line 169 creates a new <TT>String</TT> object, <TT>s4</TT>. Line 170 invokes theassignment operator. Line 171 prints the results. You might be thinking, &quot;Theassignment operator is defined to take a constant <TT>String</TT> reference in line21, but here the program passes in a C-style string. Why is this legal?&quot;</P><P>The answer is that the compiler expects a <TT>String</TT>, but it is given a characterarray. Therefore, it checks whether it can create a <TT>String</TT> from what itis given. In line 12, you declared a constructor that creates <TT>String</TT>s fromcharacter arrays. The compiler creates a temporary <TT>String</TT> from the characterarray and passes it to the assignment operator. This is known as implicit casting,or promotion. If you had not declared--and provided the implementation for--the constructorthat takes a character array, this assignment would have generated a compiler error.<H3 ALIGN="CENTER"><A NAME="Heading47"></A><FONT COLOR="#000077">Linked Lists andOther Structures</FONT></H3><P>Arrays are much like Tupperware. They are great containers, but they are of afixed size. If you pick a container that is too large, you waste space in your storagearea. If you pick one that is too small, its contents spill all over and you havea big mess.</P><P>One way to solve this problem is with a linked list. A linked list is a data structurethat consists of small containers that are designed to fit and that are linked togetheras needed. The idea is to write a class that holds one object of your data--suchas one <TT>CAT</TT> or one <TT>Rectangle</TT>--and that can point at the next container.You create one container for each object that you need to store, and you chain themtogether as needed.</P><P>The containers are called nodes. The first node in the list is called the head,and the last node in the list is called the tail.</P><P>Lists come in three fundamental forms. From simplest to most complex, they are<UL>	<LI>Singly linked	<P>	<LI>Doubly linked	<P>	<LI>Trees</UL><P>In a singly linked list, each node points forward to the next one, but not backward.To find a particular node, start at the top and go from node to node, as in a treasurehunt (&quot;The next node is under the sofa&quot;). A doubly linked list enablesyou to move backward and forward in the chain. A tree is a complex structure builtfrom nodes, each of which can point in two or three directions. Figure 11.5 showsthese three fundamental structures.</P><P>Computer scientists have created even more complex and clever data structures,nearly all of which rely on interconnecting nodes. Listing 11.13 shows how to createand use a simple linked list.<BR><BR><A NAME="Heading48"></A><A HREF="11zcp05.jpg" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/art/ch11/11zcp05.jpg"><FONT COLOR="#000077">Figure11.5</FONT></A><FONT COLOR="#000077"> </FONT><I>Linked lists.</I></P><P><A NAME="Heading49"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 11.13. Implementinga linked list</B></FONT><FONT SIZE="2" COLOR="#000077"><B>.</B></FONT></P><PRE><FONT COLOR="#0066FF">1:       // Listing 11.132:       // Linked list simple implementation3:4:       #include &lt;iostream.h&gt;5:6:       // object to add to list7:       class CAT8:       {9:       public:10:         CAT() { itsAge = 1;}11:         CAT(int age):itsAge(age){}12:         ~CAT(){};13:         int GetAg

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -