📄 index.html
字号:
<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> 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<double>(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 << "one half seven is " << halfd << "\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 >> x )
. . .</pre></tt>
</blockquote>
<ul>
<li>The <tt>>></tt> operator returns <tt>istream&</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& 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 < size; i++)
values[i] = v[i];
}
int& SafeArray::operator[](int index)
{
assert((index >= 0) && (index < size));
return values[i];
}
int SafeArray::operator[](int index) const;
{
assert((index >= 0) && (index < 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 << "one random value " << a() << "\n";
cout << "and another " << a() << "\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 << "random value between 3 and 7 " << r() << "\n";
cout << "random value between 3 and 10 " << r(10) << "\n";
cout << "random value between 23 and 30 " << r(23, 30) << "\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>&</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>&&</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>-></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 ( <= 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 => 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 + -