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

📄 chapter12.html

📁 《C++编程思想》中文版。。。。。。。。。。。。。
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<!--
This document was converted from RTF source: 
By rtftohtml 4.19
See http://www.sunpack.com/RTF
Filename:TIC2Vone.rtf
Application Directory:C:\TOOLS\RTF2HTML\
Subject:
Author:Bruce Eckel
Operator:Bruce Eckel
Document Comments:
Version Comments:
Comments:
Keywords:
Translation Date:09/27/2001
Translation Time:05:25:46
Translation Platform:Win32
Number of Output files:22
This File:Chapter12.html
SplitDepth=1
SkipNavPanel=1
SkipLeadingToc=1
SkipTrailingToc=1
GenContents=1
GenFrames=1
GenIndex=1
-->
<HEAD lang="en"><META http-equiv="Content-Type" content="text/html">
<TITLE>12: Operator Overloading</TITLE>
</HEAD>

<BODY  BGCOLOR="#FFFFFF"><DIV ALIGN="CENTER">
  <a href="http://www.MindView.net">
  <img src="mindview-head.gif" alt="MindView Inc." BORDER = "0"></a>
  <CENTER>
    <FONT FACE="Verdana" size = "-1">
    [ <a href="README-HTML.txt">Viewing Hints</a> ]
    [ <a href="http://www.mindview.net/CPPServices/SolutionGuide.html">Exercise Solutions</a> ]
    [ <a href="http://www.mindview.net/ThinkingInCPP2e.html">Volume 2</a> ]
    [ <a href="http://www.mindview.net/MailingList.html">Free Newsletter</a> ] <br>
    [ <a href="http://www.mindview.net/CPPServices/#PublicSeminars">Seminars</a> ]
    [ <a href="http://www.mindview.net/CPPServices/#SeminarsOnCD">Seminars on CD ROM</a> ]
    [ <a href="http://www.mindview.net/CPPServices/#ConsultingServices">Consulting</a> ]
    </FONT>
  <H2><FONT FACE="Verdana">
  Thinking in C++, 2nd ed. Volume 1</FONT></H2></FONT>
  <H3><FONT FACE="Verdana">&copy;2000 by Bruce Eckel</FONT></H3></FONT>
  
    <FONT FACE="Verdana" size = "-1">
     [ <a href="Chapter11.html">Previous Chapter</a> ] 
    [ <a href="Contents.html">Table of Contents</a> ] 
    [ <a href="DocIndex.html">Index</a> ]
     [ <a href="Chapter13.html">Next Chapter</a> ] 
    </FONT>
    
  </CENTER>
  </P></DIV><A NAME="_Toc472654946"></A><FONT FACE = "Verdana"><H1 ALIGN="LEFT">
12:
<A NAME="_Toc305593233"></A><A NAME="_Toc305628705"></A><A NAME="_Toc312373971"></A>Operator
Overloading</H1></FONT>
<A NAME="Heading348"></A><FONT FACE = "Verdana"><H1 ALIGN="LEFT">
</H1></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Verdana" SIZE=4>Operator overloading
<A NAME="Index1962"></A>is just &#8220;syntactic
sugar<A NAME="Index1963"></A><A NAME="Index1964"></A>,&#8221; which means it is
simply another way for you to make a function call.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The difference is that the arguments for
this function don&#8217;t appear inside parentheses, but instead they surround
or are next to characters you&#8217;ve always thought of as immutable
operators.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There are two differences between the use
of an operator and an ordinary function call. The syntax is different; an
operator is often &#8220;called&#8221; by placing it between or sometimes after
the arguments. The second difference is that the compiler determines which
&#8220;function&#8221; to call. For instance, if you are using the operator
<B>+</B> with floating-point arguments, the compiler &#8220;calls&#8221; the
function to perform floating-point addition (this &#8220;call&#8221; is
typically the act of inserting in-line code, or a floating-point-processor
instruction). If you use operator <B>+</B> with a floating-point number and an
integer, the compiler &#8220;calls&#8221; a special function to turn the
<B>int</B> into a <B>float</B>, and then &#8220;calls&#8221; the floating-point
addition code.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">But in C++, it&#8217;s possible to define
new operators that work with classes. This definition is just like an ordinary
function definition except that the name of the function consists of the keyword
<B>operator</B> <A NAME="Index1965"></A>followed by the operator. That&#8217;s
the only difference, and it becomes a function <A NAME="Index1966"></A>like any
other function, which the compiler calls when it sees the appropriate
pattern.</FONT><A NAME="_Toc305593234"></A><A NAME="_Toc305628706"></A><A NAME="_Toc312373972"></A><A NAME="_Toc472654947"></A><BR></P></DIV>
<A NAME="Heading349"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Warning &amp; reassurance</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It&#8217;s tempting to become
overenthusiastic with operator overloading. It&#8217;s a fun toy, at first. But
remember it&#8217;s <I>only</I> syntactic sugar, another way of calling a
function. Looking at it this way, you have no reason to overload an operator
except if it will make the code involving your class easier to write and
especially easier to <I>read</I>. (Remember, code is read much more than it is
written.) If this isn&#8217;t the case, don&#8217;t bother.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Another common response to operator
overloading is panic; suddenly, C operators have no familiar meaning anymore.
&#8220;Everything&#8217;s changed and all my C code will do different
things!&#8221; This isn&#8217;t true. All the operators used in expressions that
contain only built-in data types cannot be changed. You can never overload
operators such that</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>1 &lt;&lt; 4;</PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">behaves differently, or</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>1.414 &lt;&lt; 2;</PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">has meaning. Only an expression
containing a user-defined type can have an overloaded
operator.</FONT><A NAME="_Toc305593235"></A><A NAME="_Toc305628707"></A><A NAME="_Toc312373973"></A><A NAME="_Toc472654948"></A><BR></P></DIV>
<A NAME="Heading350"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Syntax</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Defining an overloaded
<A NAME="Index1967"></A>operator is like defining a function, but the name of
that function is <B>operator@</B>, in which <B>@</B> represents the operator
that&#8217;s being overloaded. The number of arguments in the overloaded
operator&#8217;s argument list depends on two
factors<A NAME="Index1968"></A><A NAME="Index1969"></A><A NAME="Index1970"></A><A NAME="Index1971"></A><A NAME="Index1972"></A><A NAME="Index1973"></A><A NAME="Index1974"></A><A NAME="Index1975"></A><A NAME="Index1976"></A>:</FONT><BR></P></DIV>
<OL>
<LI><FONT FACE="Verdana">	</FONT><FONT FACE="Georgia">Whether it&#8217;s a unary
operator (one argument) or a binary operator (two
arguments).</FONT><LI><FONT FACE="Verdana">	</FONT><FONT FACE="Georgia">Whether
the operator is defined as a global function (one argument for unary, two for
binary) or a member function (zero arguments for unary, one for binary &#8211;
the object becomes the left-hand
argument).</FONT></OL><DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;s a
small class that shows the syntax for operator overloading:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C12:OperatorOverloadingSyntax.cpp</font>
#include &lt;iostream&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>class</font> Integer {
  <font color=#0000ff>int</font> i;
<font color=#0000ff>public</font>:
  Integer(<font color=#0000ff>int</font> ii) : i(ii) {}
  <font color=#0000ff>const</font> Integer
  <font color=#0000ff>operator</font>+(<font color=#0000ff>const</font> Integer&amp; rv) <font color=#0000ff>const</font> {
    cout &lt;&lt; <font color=#004488>"operator+"</font> &lt;&lt; endl;
    <font color=#0000ff>return</font> Integer(i + rv.i);
  }
  Integer&amp;
  <font color=#0000ff>operator</font>+=(<font color=#0000ff>const</font> Integer&amp; rv) {
    cout &lt;&lt; <font color=#004488>"operator+="</font> &lt;&lt; endl;
    i += rv.i;
    <font color=#0000ff>return</font> *<font color=#0000ff>this</font>;
  }
};

<font color=#0000ff>int</font> main() {
  cout &lt;&lt; <font color=#004488>"built-in types:"</font> &lt;&lt; endl;
  <font color=#0000ff>int</font> i = 1, j = 2, k = 3;
  k += i + j;
  cout &lt;&lt; <font color=#004488>"user-defined types:"</font> &lt;&lt; endl;
  Integer ii(1), jj(2), kk(3);
  kk += ii + jj;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The two overloaded operators are defined
as inline member functions that announce when they are called. The single
argument is what appears on the right-hand side of the operator for binary
operators. Unary operators have no arguments when defined as member functions.
The member function is called for the object on the left-hand side of the
operator.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">For non-conditional operators
(conditionals usually return a Boolean value), you&#8217;ll almost always want
to return <A NAME="Index1977"></A><A NAME="Index1978"></A>an object or reference
of the same type you&#8217;re operating on if the two arguments are the same
type. (If they&#8217;re not the same type, the interpretation of what it should
produce is up to you.) This way,
<A NAME="Index1979"></A><A NAME="Index1980"></A><A NAME="Index1981"></A>complicated
expressions can be built up:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>kk += ii + jj;</PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>operator+</B> produces a new
<B>Integer</B> (a temporary) that is used as the <B>rv</B> argument for the
<B>operator+=</B>. This temporary is destroyed as soon as it is no longer
needed.</FONT><A NAME="_Toc305593236"></A><A NAME="_Toc305628708"></A><A NAME="_Toc312373974"></A><A NAME="_Toc472654949"></A><BR></P></DIV>
<A NAME="Heading351"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Overloadable operators</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Although you can overload
<A NAME="Index1982"></A><A NAME="Index1983"></A>almost all the operators
available in C, the use of operator overloading is fairly restrictive. In
particular, you cannot combine operators that currently have no meaning in C
(such as <B>**</B> to represent exponentiation), you cannot change the
evaluation precedence of operators, and you cannot change the number of
arguments required by an operator. This makes sense &#8211; all of these actions
would produce operators that confuse meaning rather than clarify
it.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The next two subsections give examples of
all the &#8220;regular&#8221; operators, overloaded in the form that
you&#8217;ll most likely
use.</FONT><A NAME="_Toc312373975"></A><A NAME="_Toc472654950"></A><BR></P></DIV>
<A NAME="Heading352"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Unary operators</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The following example shows the syntax to
overload all the unary
operators<A NAME="Index1984"></A><A NAME="Index1985"></A>, in the form of both
global functions (non-member <B>friend </B>functions) and as member functions.
These will expand upon the <B>Integer </B>class shown previously and add a new
<B>byte </B>class. The meaning of your particular operators will depend on the
way you want to use them, but consider the client programmer before doing
something unexpected.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here is a catalog of all the unary
functions:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C12:OverloadingUnaryOperators.cpp</font>
#include &lt;iostream&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#009900>// Non-member functions:</font>
<font color=#0000ff>class</font> Integer {
  <font color=#0000ff>long</font> i;
  Integer* This() { <font color=#0000ff>return</font> <font color=#0000ff>this</font>; }
<font color=#0000ff>public</font>:
  Integer(<font color=#0000ff>long</font> ll = 0) : i(ll) {}
  <font color=#009900>// No side effects takes const&amp; argument:</font>
  <font color=#0000ff>friend</font> <font color=#0000ff>const</font> Integer&amp;
    <font color=#0000ff>operator</font>+(<font color=#0000ff>const</font> Integer&amp; a);
  <font color=#0000ff>friend</font> <font color=#0000ff>const</font> Integer
    <font color=#0000ff>operator</font>-(<font color=#0000ff>const</font> Integer&amp; a);

⌨️ 快捷键说明

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