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

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<ul>
	<li>Conversion <i>to</i> a user-defined type (cont.):
	<p>If addition is <i>not</i> a member function, then this works too:</p>
		<blockquote><tt>
			b = 2 + a;
		</tt></blockquote>
	</li>
	<li>Use <tt>explicit</tt> keyword to inhibit implicit conversions
		(<i>coercion</i>s)</li>
</ul>

</font>

<hr><h2><font color="#009999">17.8 Overloading Conversion Operators</font></h2>
<font size="+1">

<ul>
	<li>Convert <i>from</i> a user-defined type</li>
	<li>An operator must be supplied for each type to convert to</li>
	<li>Definition:
		<ul>
			<li>Must be a member function</li>
			<li>Has a type as its name</li>
			<li>Has no return type</li>
			<li>Takes no arguments</li>
		</ul>
	<li>May be used implicitly, or called explicitly (<i>cast</i>)</li>
</ul>

<font color="#009999"><b>Note:</b></font>&nbsp;&nbsp; The compiler
	performs at most one level of user-defined type conversion when matching an
	overloaded function.

</font>

<hr><h2><font color="#009999">17.8 Example - Overloading Conversion
	Operators</font></h2>
<font size="+1">

Convert a <tt>Fraction</tt> to a <tt>double</tt>:

<blockquote><tt>
<pre>Fraction::operator double() const
{
   <font color="#0000cc">// Convert numerator to double, then do division</font>
   return static_cast&lt;double&gt;(top) / bottom;
}</pre></tt>
</blockquote>

Can be used:

<blockquote></tt>
<pre>Fraction a(1, 2);
double d = 7.0;
double halfd = d * a; <font color="#0000cc">// a is converted to double to do multiplication</font>
cout &lt;&lt; "one half seven is " &lt;&lt; halfd &lt;&lt; "\n";</pre></tt>
</blockquote>

</font>

<hr><h2><font color="#009999">17.8.1 Stream Loops and Conversion
	Operators</font></h2>
<font size="+1">

Consider the familiar construct:

<blockquote><tt>
<pre>while( cin &gt;&gt; x )
   . . .</pre></tt>
</blockquote>

<ul>
	<li>The <tt>&gt;&gt;</tt> operator returns <tt>istream&amp;</tt></li>
	<li>Not a valid boolean expression</li>
	<li><tt>istream</tt> provides a conversion operator that returns
		<tt>false</tt> on end of input or on error</li>
</ul>

</font>

<hr><h2><font color="#009999">17.9 Overloading the Subscript
	Operator</font></h2>
<font size="+1">

<ul>
	<li>Often defined on an indexable container (<tt>vector</tt> or
		<tt>map</tt>)</li>
	<li>Explicit argument is the index</li>
	<li>Result is the value stored at the given position</li>
	<li>Return a reference to the value to get an L-value</li>
	<li>Must be a member function</li>
	<li>operator<tt>[][]</tt> does <b>not</b> exist</li>
</ul>

</font>

<hr><h2><font color="#009999">17.9 Example: Overloading the Subscript
	Operator</font></h2>
<font size="+1">

<p>Implementation of a "safe array":</p>

<ul>
	<li>The subscript operator checks that index is valid</li>
	<li>First (non-const) version returns a reference, an L-value</li>
	<li>The second version is <tt>const</tt>, returns a copy
	</li>
</ul>

</font>

<hr><h2><font color="#009999">17.9 Example: Overloading the Subscript
	Operator (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>class SafeArray
{
public:
   SafeArray(int s);
   SafeArray(const int v[], int s);
   int&amp; operator[](int i);
   int operator[](int i) const;
   private:
   int size;
   int* values;
};

SafeArray::SafeArray(int s) : size(s), values(new int[size]) {}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.9 Example: Overloading the Subscript
	Operator (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>SafeArray::SafeArray(const int v[], int s) : size(s)
{
   values = new int[size];
   for (int i = 0; i &lt; size; i++)
   values[i] = v[i];
}

int&amp; SafeArray::operator[](int index)
{
   assert((index &gt;= 0) &amp;&amp; (index &lt; size));
   return values[i];
}

int SafeArray::operator[](int index) const;
{
   assert((index &gt;= 0) &amp;&amp; (index &lt; size));
   return values[i];
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.10 Overloading the Function Call
	Operator</font></h2>

<font size="+1">

<ul>
	<li>Objects can be used as functions (<i>function object</i>)</li>
	<li>Must be defined as a member function</li>
	<li>Can carry (and change) its own data values</li>
	<li><u>Only</u> operator where the number of arguments is <i>not</i>
		fixed</li>
	<li>Can be passed where template functions can't</li>
	<li>Used extensively by various generic algorithms in the STL (chptr. 24)</li>
</ul>

</font>

<hr><h2><font color="#009999">17.10 Example:  The Function Call
	Operator</font></h2>

<font size="+1">

<ul>
	<li>Simple to write a function that takes no arguments and returns a random
		number on <nobr>[1, 100]</nobr></li>
	<li>More difficult to write a similar function (no args) that returns
		a value on [a, b], where a and b aren't known until run time</li>
	<li>A function object makes it simple:</li>
</ul>

</font>

<hr><h2><font color="#009999">17.10 Example:  The Function Call
	Operator</font></h2>

<font size="+1">

<blockquote>
<pre>class RandomInt
{
public:
   RandomInt(int ia, int ib);
   int operator()();
private:
   int a, b;
};

RandomInt::RandomInt(int ia, int ib) : a(ia), b(ib) {}

int RandomInt::operator()()
{
   return a + rand() % (b - a + 1);
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.10 Example:  The Function Call
	Operator</font></h2>

<font size="+1">

<p>Declare an instance, then use it as a function:

<blockquote>
<pre>RandomInt a(7, 15); <font color="#0000cc">// Return random values from 7 to 15</font>
cout &lt;&lt; "one random value " &lt;&lt; a() &lt;&lt; "\n";
cout &lt;&lt; "and another " &lt;&lt; a() &lt;&lt; "\n";</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.10 Example 2:  Variable arguments</font></h2>

<font size="+1">

<blockquote>
<pre>class RandomInt
{
public:
   RandomInt(int ia, int ib);
   int operator()();
   int operator()(int nb);
   int operator()(int na, nb);
private:
   int a, b;
};</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.10 Example 2:  Variable arguments (cont.)
	</font></h2>

<font size="+1">

<blockquote>
<pre>RandomInt::RandomInt(int ia, int ib) : a(ia), b(ib) {}

int RandomInt::operator()()
{ return a + rand() % (b - a + 1); }

int RandomInt::operator()(int nb)
{ return a + rand() % (nb - a + 1); }

int RandomInt::operator()(int na, int nb)
{ return na + rand() % (nb - na + 1); }</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.10 Example 2:  Variable arguments</font></h2>

<font size="+1">

<p>The function selected will be determined by the number of arguments provided:
<blockquote>
<pre>RandomInt r(3, 7);
cout &lt;&lt; "random value between 3 and 7 " &lt;&lt; r() &lt;&lt; "\n";
cout &lt;&lt; "random value between 3 and 10 " &lt;&lt; r(10) &lt;&lt; "\n";
cout &lt;&lt; "random value between 23 and 30 " &lt;&lt; r(23, 30) &lt;&lt; "\n";</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">Advanced Topic 17.5</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Other Operators</font></h3>

Operators not commonly used, hence, not commonly overloaded:
<ul>
	<li>Comma operator</li>
		<ul>
			<li>Has lower precedence than assignment</li>
		</ul>
	<li><tt>&amp;</tt>, <tt>|</tt> and <tt>^</tt>
		<ul>
			<li><tt>^</tt> has lower precedence than addition.</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">Advanced Topic 17.5</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Other Operators (cont.)</font></h3>

<ul>
	<li><tt>&amp;&amp;</tt> and <tt>||</tt>
		<ul>
			<li>Lose their short-circuit logic when overloaded</li>
		</ul>
	</li>
	<li><tt>~</tt> and <tt>!</tt></li>
	<li><tt>-&gt;</tt>
		<ul>
			<li>Can make <i>smart pointers</i></li>
		</ul>
	<li><tt>new</tt> and <tt>delete</tt></li>
</ul>

</font>

<hr><h2><font color="#009999">Advanced Topic 17.6</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Inline Functions</font></h3>

<ul>
	<li>Avoid overhead of function calls</li>
	<li>Body expanded in place of each call</li>
	<li>Only for very short functions ( &lt;= 3 lines )</li>
</ul>

To define:
<ul>
	<li>Precede definition w/ <tt>inline</tt></li>
	<li>Place in interface file</li>
	<li>Same for member function</li>
	<li>Alternatively, define member function inside class definition</li>
</ul>

</font>

<hr><h2><font color="#009999">17.11 Case Study: Matrices</font></h2>

<font size="+1">

Operations on matrices:

<ul>
	<li>Addition</li>
	<li>Scalar multiplication</li>
	<li>Matrix multiplication</li>
		<ul>
			<li>Single row by single column</li>
			<li>Apply above algorithm to all rows of first by all columns in
				second</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">17.11 Case Study: Matrices</font></h2>

<font size="+1">

<p>Implementation:</p>

<ul>
	<li>2D array:
		<ul>
			<li>Indices not checked</li>
			<li>Need helper functions to copy</li>
			<li>Can't use standard arithmetic operators</li>
		</ul>
	</li>
	<li>Create <tt>Matrix</tt>:
		<ul>
			<li>Number of ROWS and COLUMNS variable; can't use a 2D array
				underneath</li>
			<li>Use a 1D array.  So, element<sub><i>i,j</i></sub> will be
				found at
				<blockquote>
					<tt>i * COLUMNS + j</tt>
				</blockquote>
			</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">17.11 Case Study: Matrices (cont.)</font></h2>

<font size="+1">

<ul>
	<ul>
		<li>Subscripting:
			<ol>
				<li>Overload function-call operator, OR</li>
				<li>Subscript (<tt>[]</tt>) returns <tt>MatrixRow</tt>, which
					provides its own (<tt>[]</tt>) operator</li>
			</ol>
		<li>We choose option 2
			<ul>
				<li>const vs. non-const =&gt; also provide a
					<tt>ConstMatrixRow</tt></li>
			</ul>
		</li>
		<li>Small functions will be <tt>inline</tt>
	</ul>
</ul>

</font>

<hr><h2><font color="#009999">17.11 Case Study: Matrices
	(<tt>matrix1.h</tt>)</font></h2>

<font size="+1">

<script><!--
	iframeWrapCode( "matrix1.h", "90%", "75%" )
//--></script>

</font>

<hr><h2><font color="#009999">17.11 Case Study: Matrices
	(<tt>matrix1.cpp</tt>)</font></h2>

<font size="+1">

Implementation for the <tt>Matrix</tt> class:

<script><!--
	iframeWrapCode( "matrix1.cpp", "90%", "75%" )
//--></script>

</font>

<hr><h2><font color="#009999">17.11 Case Study: Matrices
	(<tt>matrixtest1.cpp</tt>)</font></h2>

<font size="+1">

<script><!--
	iframeWrapCode( "matrixtest1.cpp", "90%", "60%" )
//--></script>

</font>

<hr><h2><font color="#009999">Chapter Summary</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<ol>
	<li>Define new meanings for C++ operators</li>
	<li>Member vs. nonmember operators</li>
	<li>Extend new types using stream I/O operators</li>
	<li>Simulate pointers by defining operators on iterators</li>
	<li>Operators to define behavior of conversions</li>
	<li>Function objects</li>
</ol>

</font>

</body>
</html>

⌨️ 快捷键说明

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