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

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 3 页
字号:
	iframeWrapCode( "fraction.h", "90%", "75%" )
	//--></script>

</font>

<hr><h2><font color="#009999">17.2&nbsp;&nbsp;Case Study: Fractional Numbers
	(<tt>fraction.cpp</tt>)</font></h2>
<font size="+1">

<p>(Discussion follows)

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

</font>

<hr><h2><font color="#009999">17.2&nbsp;&nbsp;Case Study: Fractional Numbers
	(<tt>fractiontest.cpp</tt>)</font></h2>
<font size="+1">

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

</font>

<hr><h2><font color="#009999">17.3  Overloading Simple Arithmetic
	Operators</font></h2>
<font size="+1">

<ul>
	<li><tt> = + - * / %</tt></li>
	<li>Parameters types need <b>not</b> match
		<blockquote><tt>
			Time Time::operator+( int seconds ) const;
		</tt></blockquote>
	</li>
	<li>Supply behavior that is analogous to the arithmetic operators;
		intuitive</li>
	<li><b>E.g.</b> (fraction.cpp, lines 61-67)
		<br><i>(See next slide)</i>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">17.3  Simple Arithmetic Operators - Fraction
	Example</font></h2>
<font size="+1">

<i>a/b + c/d</i> is defined to be <i>(a*d + c*d)/(b*d)</i><br><br>

<blockquote>
<pre>Fraction operator+(const Fraction&amp; left, const Fraction&amp; right)
{
   Fraction result(left.numerator() * right.denominator()
      + right.numerator() * left.denominator(),
      left.denominator() * right.denominator());
   return result;
}</pre>
</blockquote>

<p>The remaining operations are defined similarly

</font>

<hr><h2><font color="#009999">17.3  Unary Arithmetic Operators</font></h2>
<font size="+1">

<ul>
	<li> <tt>+ - * &amp;</tt> have both binary and unary forms</li>
	<li>To overload unary form, reduce the number of parameters by one</li>
	<li><b>E.g.:</b>
		<blockquote>
<pre>Fraction operator-(const Fraction&amp; value)
{
   Fraction result(-value.numerator(), value.denominator());
   return result;
}</pre>
		</blockquote>
	</li>
	<li>A unary operator defined as a member function takes no arguments
		(sect. 17.6)</li>
</ul>

</font>

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

<ul>
	<li>Similar to the arithmetic operators
	<li><i>Not</i> supplied automatically</li>
	<li>Typically return a <tt>bool</tt>
	<li><b>E.g.:</b>  <tt>Time</tt>s are equal <=> difference is 0
		<blockquote>
<pre>bool operator==(const Time&amp; a, const Time&amp; b)
{
   return a.seconds_from(b) == 0;
}</pre>
		</blockquote>
	</li>
</ul>

</font>

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

<ul>
	<li><b>E.g.</b>, from the <tt>Fraction</tt> class:
		<blockquote>
<pre>bool operator==(const Fraction&amp;amp; left, const Fraction&amp;amp; right)
{
   return left.numerator() * right.denominator()
      == right.numerator() * left.denominator();
}

bool operator&lt;(const Fraction&amp; left, const Fraction&amp; right)
{
   return left.numerator() * right.denominator()
      &lt; right.numerator() * left.denominator();
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">Productivity Hint 17.2</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Define Comparisons in Terms of Each Other</font></h3>

<ul>
	<li>Write 1 or 2 member functions; equality, and strict inequality</li>
	<li>Define all comparisons in terms of these functions</li>
	<li><b>E.g.:</b>  <tt>Fraction</tt> class (fraction.cpp)
		<ul>
			<li>A single <tt>compare</tt> method (line 97), returns an
				<tt>int</tt></li>
			<li>All 6 comparison operators (lines 104-132) call <tt>compare</tt></li>
		</ul>
	</li>
</ul>

</font>

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

<h3><font color="#009999">Symmetry and Conversion</font></h3>

<ul>
	<li>Arithmetic and comparison operators are generally nonmember
		functions</li>
	<li>No implicit conversions of left operand for member functions:
		<ul>
			<p>Consider <tt>Fraction a;</tt></p>
			<li><tt>( a == 2 )</tt> works fine (given the constructors)</li>
			<li><tt>( 2 == a )</tt> will <b>not</b> work if equality is a member
				function.
			</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">17.5 Overloading Input <tt>&gt;&gt;</tt> and
	Output <tt>&lt;&lt;</tt></font></h2>
<font size="+1">

<ul>
	<li>Originally shift operators</li>
	<li>Almost always overloaded for I/O</li>
	<li>Overloaded exactly as the binary arithmetic operators</li>
	<li>Should be non-member functions</li>
</ul>

</font>

<hr><h2><font color="#009999">17.5.1 Stream Output &lt;&lt;</font></h2>
<font size="+1">

<ul>
	<li>Output stream class (chptr. 12) provides ability to write a single
		character</li>
	<li>Stream library provides insertion operator for all built-in types:
		<blockquote><tt>
			ostream&amp; operator&lt;&lt;(ostream&amp; out, double value);
		</tt></blockquote>
		<p><b>Note:</b> the stream itself is returned</p>
	</li>
	<li><b>E.g.:</b>  Overload output for <tt>Fraction</tt>
		<blockquote><tt>
<pre>ostream&amp; operator&lt;&lt;( ostream &amp;out, const Fraction &amp;value )
{
   out &lt;&lt; value.numerator() &lt;&lt; "/" &lt;&lt; value.denominator();
   return out;
}</pre>
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">17.5.2 Stream Input &gt;&gt;</font></h2>
<font size="+1">

<ul>
	<li>Stream library provides for all built-in types</li>
	<li>Can be overloaded, much like the output operator</li>
	<li>2nd parameter is a <i>non-const</i> reference
	<li><b>E.g.:</b>  Input operator for <tt>Time</tt></li>
</ul>

</font>

<hr><h2><font color="#009999">17.5.2 Stream Input &gt;&gt; (cont.)</font></h2>
<font size="+1">

<blockquote>
	Assume a <tt>Time</tt> is input as 3 separate integers,
	<tt>9 15 00</tt> to represent 9:15:00 a.m.
	<br><br><tt>
<pre>istream&amp; operator&gt;&gt;(istream&amp; in, Time&amp; a)
{
   int hours;
   int minutes;
   int seconds;
   in &gt;&gt; hours &gt;&gt; minutes &gt;&gt; seconds;
   a = Time(hours, minutes, seconds);
   return in;
}</pre></tt>
		</blockquote>
	</li>
</ul>

</font>

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

<h3><font color="#009999">Peeking at the Input</font></h3>

<p>You may put a single character back into the stream.

<p><b>E.g.:</b>  We want to allow a user to input a <tt>Fraction</tt> as
	a single integer (<tt>7</tt>), or as an integer, slash, integer (<tt>3/4</tt>)

</font>

<hr><h2><font color="#009999">Advanced Topic 17.3 (cont.)</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<blockquote>
<pre>istream&amp; operator&gt;&gt;(istream&amp; in, Fraction&amp; r)
{
   int t, b;
   <font color="#0000cc">// Read the top</font>
   in &gt;&gt; t;
   <font color="#0000cc">// If there is a slash, read the next number</font>
   char c;
   in &gt;&gt; c;
   if (c == '/')
      in &gt;&gt; b;
   else
   {
      in.putback(c);
      b = 1;
   }
   r = Fraction(t, b);
   return in;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.6&nbsp;&nbsp;Overloading Increment
	and Decrement Operators</font></h2>
<font size="+1">

<ul>
	<li>Generally defined as member functions</li>
	<li>Two versions of each:
		<ol>
			<li>prefix version:&nbsp;&nbsp;<tt>++x</tt></li>
			<li>postfix version:&nbsp;&nbsp;<tt>x++</tt></li>
		</ol>
	</li>
	<li>C++ uses an extra argument to distinguish the postfix form</li>
</ul>

</font>

<hr><h2><font color="#009999">17.6&nbsp;&nbsp;Overloading Increment
	and Decrement Operators</font></h2>
<font size="+1">

<ul>
	<li><b>E.g.:</b>&nbsp;&nbsp;Increments for <tt>Fraction</tt>
		<br>Notice:
		<ul>
			<li>Prefix returns a reference</li>
			<li>Postfix does more work</li>
			</li>
		</ul>
		<blockquote>
<pre>class Fraction
{
   . . .
   Fraction&amp; operator++();&nbsp;&nbsp;<font color="#0000cc">// Prefix form</font>
   Fraction operator++(int unused);&nbsp;&nbsp;<font color="#0000cc">// Postfix form</font>
   . . .
};</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">17.6&nbsp;&nbsp;Overloading Increment
	and Decrement Operators (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>Fraction&amp; Fraction::operator++()
{
   top += bottom;
   return *this;
}
Fraction Fraction::operator++(int unused)
{
   Fraction clone(top, bottom);
   top += bottom;
   return clone;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.6.1 Iterators and Overloaded Operators</font></h2>
<font size="+1">

<ul>
	<li>Iterators (Sect. 16.5) can be used just like pointers (Chptr. 10) to
		process arrays</li>
	<li>Iterators can be used (in varying capacities) on all standard
		containers</li>
	<li>Operators overloaded for iterators:
		<table>
			<tr><td width='25%'><tt>+</tt></td><td>addition</td></tr>
			<tr><td><tt>==</tt></td><td>comparison</td></tr>
			<tr><td><tt>*</tt></td><td>dereference</td></tr>
			<tr><td><tt>++</tt></td><td>increment (post and pre)</td></tr>
		</table>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">17.6.1 Example: Implementing Iterator Operators
	</font></h2>
<font size="+1">

<p>Recall <tt>Iterator</tt>, defined on our <tt>List</tt> of strings.  We can
now overload the standard operators:</p>

<blockquote>
<pre>Iterator&amp; Iterator::operator++(int)
{
   position = position-&gt;next;
   return *this;
}

string Iterator::operator*() const
{
   assert(position != NULL);
   return position-&gt;data;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.6.1 Example: Implementing Iterator Operators
	(cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>bool Iterator::operator==(const Iterator&amp; b) const
{
   return position == b.position;
}

bool Iterator::operator!=(const Iterator&amp; b) const
{
   return position != b.position;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">17.7 Overloading the Assignment
	Operators</font></h2>
<font size="+1">

<h3><font color="#009999">The Assignment Operator,
	&nbsp;&nbsp;<tt>=</tt></font></h3>
<ul>
	<li>Must be a member function</li>
	<li>Is <i>automatically generated</i>
		<ul>
			<li>Member-wise copy</li>
			<li>Destructor and copy constructor also supplied by compiler</li>
		</ul>
	</li>
	<li>Desired behavior for many classes</li>
	<li>Explicitly supply if class has outside references</li>
</ul>

</font>

<hr><h2><font color="#009999">17.7.1 Overloading Compound Assignment
	Operators&nbsp;&nbsp;(<tt>+= *=</tt>, etc.)</font></h2>
<font size="+1">

<ul>
	<li><i>Never</i> supplied automatically</li>
	<li>Use existing arithmetic and assignment operators to define compound
		operator</li>
	<li><b>E.g.:</b>&nbsp;&nbsp;<tt>+=</tt> for <tt>Fraction</tt></li>
		<blockquote>
<pre>Fraction&amp; Fraction::operator+=(const Fraction&amp; right)
{
   top = top * right.denominator() + bottom * right.numerator();
   bottom *= right.denominator();
   normalize();
   return *this;
}</pre>
		</blockquote>
</ul>

</font>

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

<ul>
	<li>Conversion <i>to</i> a user-defined type is handled by constructors

		<p><b>E.g.:</b>  <tt>Fraction</tt> has a constructor that takes a
			single integer.  This is okay:

		<blockquote><tt>
			Fraction a(3,4), b;<br>
			b = a + 2;&nbsp;&nbsp;<font color="#0000cc">// Addition of Fraction and integer</font>
		</tt></blockquote>

		<p>The assignment statement becomes</p>
		<blockquote><tt>
			b = a + Fraction(2);<br>
				<font color="#0000cc">// Convert right operand to Fraction, then add</font>
		</tt></blockquote>
	</li>
</ul>

</font>

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

⌨️ 快捷键说明

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