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

📄 ch20.htm

📁 vc的电子书
💻 HTM
📖 第 1 页 / 共 5 页
字号:
105:          {
106:             Array intArray(9);
107:             for (int j = 0; j< 100; j++)
108:             {
109:                intArray[j] = j;
110:                cout << "intArray[" << j << "] okay..." << endl;
111:             }
112:          }
113:          catch (Array::xBoundary)
114:          {
115:             cout << "Unable to process your input!\n";
116:          }
117:         catch (Array::xZero theException)
118:         {
119:            cout << "You asked for an Array of zero objects!" << endl;
120:            cout << "Received " << theException.GetSize() << endl;
121:         }
122:         catch (Array::xTooBig theException)
123:         {
124:            cout << "This Array is too big..." << endl;
125:            cout << "Received " << theException.GetSize() << endl;
126:         }
127:         catch (Array::xTooSmall theException)
128:         {
129:            cout << "This Array is too small..." << endl;
130:            cout << "Received " << theException.GetSize() << endl;
131:         }
132:         catch (...)
133:         {
134:            cout << "Something went wrong, but I've no idea what!\n";
135:         }
136:         cout << "Done.\n";
137:        return 0;
<TT>138: }</TT></FONT>
<FONT COLOR="#0066FF">
Output: This array is too small...
Received 9
Done.
</FONT></PRE>
<P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>The declaration of <TT>xSize</TT>
has been modified to include a member variable, <TT>itsSize</TT>, on line 32 and
a member function, <TT>GetSize()</TT>, on line 30. Additionally, a constructor has
been added that takes an integer and initializes the member variable, as shown on
line 28.<BR>
The derived classes declare a constructor that does nothing but initialize the base
class. No other functions were declared, in part to save space in the listing.</P>
<P>The <TT>catch</TT> statements on lines 113 to 135 are modified to name the exception
they catch, <TT>theException</TT>, and to use this object to access the data stored
in <TT>itsSize</TT>.


<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE: </B></FONT>Keep in mind that if you are constructing
	an exception, it is because an exception has been raised: Something has gone wrong,
	and your exception should be careful not to kick off the same problem. Therefore,
	if you are creating an <TT>OutOfMemory</TT> exception, you probably don't want to
	allocate memory in its constructor. 
<HR>


</BLOCKQUOTE>

<P>It is tedious and error-prone to have each of these <TT>catch</TT> statements
individually print the appropriate message. This job belongs to the object, which
knows what type of object it is and what value it received. Listing 20.5 takes a
more object-oriented approach to this problem, using virtual functions so that each
exception &quot;does the right thing.&quot;</P>

<P><A NAME="Heading21"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 20.5.Passing
by reference and using virtual functions in exceptions.</B></FONT>
<PRE><FONT COLOR="#0066FF">0:      #include &lt;iostream.h&gt;
1:    
2:      const int DefaultSize = 10;
3:    
4:      class Array
5:      {
6:      public:
7:         // constructors
8:         Array(int itsSize = DefaultSize);
9:         Array(const Array &amp;rhs);
10:         ~Array() { delete [] pType;}
11:    
12:         // operators
13:         Array&amp; operator=(const Array&amp;);
14:         int&amp; operator[](int offSet);
15:         const int&amp; operator[](int offSet) const;
16:    
17:         // accessors
18:         int GetitsSize() const { return itsSize; }
19:    
20:         // friend function
21:        friend ostream&amp; operator&lt;&lt; 
22:            (ostream&amp;, const Array&amp;);
23:    
24:       // define the exception classes
25:         class xBoundary {};
26:         class xSize
27:         {
28:         public:
29:            xSize(int size):itsSize(size) {}
30:            ~xSize(){}
31:            virtual int GetSize() { return itsSize; }
32:            virtual void PrintError() 
33:            { 
34:                cout &lt;&lt; &quot;Size error. Received: &quot;;
35:                cout &lt;&lt; itsSize &lt;&lt; endl; 
36:            }
37:         protected:
38:            int itsSize;
39:         };
40:    
41:         class xTooBig : public xSize
42:         {
43:         public:
44:            xTooBig(int size):xSize(size){}
45:            virtual void PrintError() 
46:            { 
47:                cout &lt;&lt; &quot;Too big! Received: &quot;;
48:                cout &lt;&lt; xSize::itsSize &lt;&lt; endl; 
49:            }
50:         };
51:    
52:         class xTooSmall : public xSize
53:         {
54:         public:
55:            xTooSmall(int size):xSize(size){}
56:            virtual void PrintError() 
57:            { 
58:                cout &lt;&lt; &quot;Too small! Received: &quot;;
59:                cout &lt;&lt; xSize::itsSize &lt;&lt; endl; 
60:            }
61:         };
62: 
63:         class xZero  : public xTooSmall
64:         {
65:         public:
66:            xZero(int size):xTooSmall(size){}
67:            virtual void PrintError() 
68:            { 
69:                cout &lt;&lt; &quot;Zero!!. Received: &quot; ;
70:                cout &lt;&lt; xSize::itsSize &lt;&lt; endl; 
71:            }
72:         };
73:    
74:         class xNegative : public xSize
75:         {
76:         public:
77:            xNegative(int size):xSize(size){}
78:            virtual void PrintError() 
79:            { 
80:                cout &lt;&lt; &quot;Negative! Received: &quot;;
81:                cout &lt;&lt; xSize::itsSize &lt;&lt; endl; 
82:            }
83:         };
84:    
85:      private:
86:         int *pType;
87:         int  itsSize;
88:      };
89:    
90:      Array::Array(int size):
91:      itsSize(size)
92:      {
93:         if (size == 0)
94:            throw xZero(size);
95:         if (size &gt; 30000)
96:            throw xTooBig(size);
97:         if (size &lt;1)
98:            throw xNegative(size);
99:         if (size &lt; 10)
100:            throw xTooSmall(size);
101:    
102:         pType = new int[size];
103:         for (int i = 0; i&lt;size; i++)
104:           pType[i] = 0;
105:      }
106:    
107:      int&amp; Array::operator[] (int offSet)
108:      {
109:          int size = GetitsSize();
110:          if (offSet &gt;= 0 &amp;&amp; offSet &lt; GetitsSize())
111:            return pType[offSet];
112:          throw xBoundary();
113:          return pType[0];
114:      }
115:    
116:      const int&amp; Array::operator[] (int offSet) const
117:      {
118:          int size = GetitsSize();
119:          if (offSet &gt;= 0 &amp;&amp; offSet &lt; GetitsSize())
120:            return pType[offSet];
121:          throw xBoundary();
122:          return pType[0];
123:      }
124:    
125:       int main()
126:       {
127: 
128:          try
129:          {
130:             Array intArray(9);
131:             for (int j = 0; j&lt; 100; j++)
132:             {
133:                intArray[j] = j;
134:                cout &lt;&lt; &quot;intArray[&quot; &lt;&lt; j &lt;&lt; &quot;] okay...\n&quot;;
135:             }
136:          }
137:          catch (Array::xBoundary)
138:         {
139:            cout &lt;&lt; &quot;Unable to process your input!\n&quot;;
140:         }
141:         catch (Array::xSize&amp; theException)
142:         {
143:            theException.PrintError();
144:         }
145:         catch (...)
146:         {
147:            cout &lt;&lt; &quot;Something went wrong!\n&quot;;
148:         }
149:         cout &lt;&lt; &quot;Done.\n&quot;;
150:        return 0;
<TT>151: }</TT></FONT>
<FONT COLOR="#0066FF">
Output: Too small! Received: 9
Done.
</FONT></PRE>
<P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>Listing 20.5 declares a virtual
method in the <TT>xSize</TT> class, <TT>PrintError()</TT>, that prints an error message
and the actual size of the class. This is overridden in each of the derived classes.<BR>
<BR>
On line 141, the exception object is declared to be a reference. When <TT>PrintError()</TT>
is called with a reference to an object, polymorphism causes the correct version
of <TT>PrintError()</TT> to be invoked. The code is cleaner, easier to understand,
and easier to maintain.
<H3 ALIGN="CENTER"><A NAME="Heading23"></A><FONT COLOR="#000077">Exceptions and Templates</FONT></H3>
<P>When creating exceptions to work with templates, you have a choice: you can create
an exception for each instance of the template, or you can use exception classes
declared outside the template declaration. Listing 20.6 illustrates both approaches.</P>

<P><A NAME="Heading24"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 20.6. Using
exceptions with templates.</B></FONT>
<PRE><FONT COLOR="#0066FF">0:      #include &lt;iostream.h&gt;
1:    
2:      const int DefaultSize = 10;
3:      class xBoundary {};
4:    
5:      template &lt;class T&gt;
6:      class Array
7:      {
8:      public:
9:         // constructors
10:         Array(int itsSize = DefaultSize);
11:         Array(const Array &amp;rhs);
12:         ~Array() { delete [] pType;}
13:    
14:         // operators
15:         Array&amp; operator=(const Array&lt;T&gt;&amp;);
16:         T&amp; operator[](int offSet);
17:         const T&amp; operator[](int offSet) const;
18:    
19:         // accessors
20:         int GetitsSize() const { return itsSize; }
21:    
22:         // friend function
23:        friend ostream&amp; operator&lt;&lt; (ostream&amp;, const Array&lt;T&gt;&amp;);
24:    
25:       // define the exception classes
26:    
27:         class xSize {};
28:    
29:      private:
30:         int *pType;
31:         int  itsSize;
32:      };
33:    
34:      template &lt;class T&gt;
35:      Array&lt;T&gt;::Array(int size):
36:      itsSize(size)
37:      {
38:         if (size &lt;10 || size &gt; 30000)
39:            throw xSize();
40:         pType = new T[size];
41:         for (int i = 0; i&lt;size; i++)
42:           pType[i] = 0;
43:      }
44: 
45:      template &lt;class T&gt;
46:      Array&lt;T&gt;&amp; Array&lt;T&gt;::operator=(const Array&lt;T&gt; &amp;rhs)
47:      {
48:         if (this == &amp;rhs)
49:            return *this;
50:         delete [] pType;
51:         itsSize = rhs.GetitsSize();
52:         pType = new T[itsSize];
53:         for (int i = 0; i&lt;itsSize; i++)

⌨️ 快捷键说明

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