📄 c++ faq lite[13]--算符重载(新).htm
字号:
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.1]">[13.1]
算符重载的作用是什么?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.2]">[13.2]
算符重载的好处是什么?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.3]">[13.3]
有什么算符重载的实例?</A> <IMG alt=UPDATED!
src="C++ FAQ Lite[13]--算符重载(新).files/updated.gif">
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.4]">[13.4]
但是算符重载使得我的类很丑陋;难道它不是应该使我的类更清晰吗?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.5]">[13.5]
什么算符能/不能被重载?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.6]">[13.6]
我能重载 <TT><FONT face=新宋体>operator==</FONT></TT> 以便比较两个 <TT><FONT
face=新宋体>char[]</FONT></TT> 来进行字符串比较吗?</A> <IMG alt=UPDATED!
src="C++ FAQ Lite[13]--算符重载(新).files/updated.gif">
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.7]">[13.7]
我能为“幂”运算创建一个 <TT><FONT face=新宋体>operator**</FONT></TT> 吗?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.8]">[13.8]
如何为<TT><FONT face=新宋体>Matrix</FONT></TT>(矩阵)类创建下标运算符?</A> <IMG alt=UPDATED!
src="C++ FAQ Lite[13]--算符重载(新).files/updated.gif">
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.9]">[13.9]
为什么<TT><FONT face=新宋体>Matrix</FONT></TT>(矩阵)类的接口不应该象数组的数组?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.10]">[13.10]
该从外(接口优先)还是从内(数据优先)设计类?</A> <IMG alt=UPDATED!
src="C++ FAQ Lite[13]--算符重载(新).files/updated.gif"> </LI></UL>
<P>
<HR>
<P><A name=[13.1]></A>
<DIV class=FaqTitle>
<H3>[13.1] 算符重载的作用是什么?</H3></DIV>
<P>它允许你为类的用户提供一个直觉的接口。
<P>算符重载允许C/C++的运算符在用户定义类型(类)上拥有一个用户定义的意义。重载的算符是函数调用的语法修饰:
<P>
<DIV class=CodeBlock><TT><FONT
face=新宋体> class Fred {<BR> public:<BR> </FONT></TT><EM>// ...</EM><TT><BR><FONT
face=新宋体> };<BR> <BR> #if 0<BR> <BR> </FONT></TT><EM>// 没有算符重载:</EM><TT><BR><FONT
face=新宋体> Fred add(Fred, Fred);<BR> Fred mul(Fred, Fred);<BR> <BR> Fred f(Fred a, Fred b, Fred c)<BR> {<BR> return add(add(mul(a,b), mul(b,c)), mul(c,a)); </FONT></TT><EM>// 哈哈,多可笑...</EM><TT><BR><FONT
face=新宋体> }<BR> <BR> #else<BR> <BR> </FONT></TT><EM>// 有算符重载:</EM><TT><BR><FONT
face=新宋体> Fred operator+ (Fred, Fred);<BR> Fred operator* (Fred, Fred);<BR> <BR> Fred f(Fred a, Fred b, Fred c)<BR> {<BR> return a*b + b*c + c*a;<BR> }<BR> <BR> #endif
</FONT></TT></DIV>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/friends.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[13.2]></A>
<DIV class=FaqTitle>
<H3>[13.2] 算符重载的好处是什么?</H3></DIV>
<P>通过重载类上的标准算符,你可以发掘类的用户的直觉。使得用户程序所用的语言是面向问题的,而不是面向机器的。
<P>最终目标是降低学习曲线并减少错误率。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/friends.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[13.3]></A>
<DIV class=FaqTitle>
<H3>[13.3] 有什么算符重载的实例?<IMG alt=UPDATED!
src="C++ FAQ Lite[13]--算符重载(新).files/updated.gif"></H3></DIV><SMALL><EM>[Recently
changed so it uses the <TT><FONT face=新宋体>std::</FONT></TT> syntax (on 7/00). <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.6]">Click
here to go to the next FAQ in the "chain" of recent changes<!--rawtext:[13.6]:rawtext--></A>.]</EM></SMALL>
<P>这里有一些算符重载的实例:
<UL>
<LI><TT><FONT face=新宋体>myString + yourString</FONT></TT> 可以连接两个
<TT><FONT face=新宋体>std::string</FONT></TT> 对象
<LI><TT><FONT face=新宋体>myDate++</FONT></TT> 可以增加一个 <TT><FONT
face=新宋体>Date</FONT></TT> 对象
<LI><TT><FONT face=新宋体>a * b</FONT></TT> 可以将两个 <TT><FONT
face=新宋体>Number</FONT></TT> 对象相乘
<LI><TT><FONT face=新宋体>a[i]</FONT></TT> 可以访问 <TT><FONT
face=新宋体>Array</FONT></TT> 对象的某个元素
<LI><TT><FONT face=新宋体>x = *p</FONT></TT> 可以反引用一个实际“指向”一个磁盘记录的
"smart pointer" —— 它实际上在磁盘上定位到 <TT><FONT face=新宋体>p
</FONT></TT>所指向的记录并返回给<TT><FONT face=新宋体>x</FONT></TT>。 </LI></UL>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/friends.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[13.4]></A>
<DIV class=FaqTitle>
<H3>[13.4] 但是算符重载使得我的类很丑陋;难道它不是应该使我的类更清晰吗?</H3></DIV>
<P>算符重载<A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.2]">使得类的用户的工作更简易</A>,而不是为类的开发者服务的!
<P>考虑一下如下的例子:
<P>
<DIV class=CodeBlock><TT><FONT
face=新宋体> class Array {<BR> public:<BR> int& operator[] (unsigned i); </FONT></TT><EM>// 有些人不喜欢这种语法</EM><TT><BR><FONT
face=新宋体> </FONT></TT><EM>// ...</EM><TT><BR><FONT
face=新宋体> };<BR> <BR> inline<BR> int& Array::operator[] (unsigned i) </FONT></TT><EM>// 有些人不喜欢这种语法</EM><TT><BR><FONT
face=新宋体> {<BR> </FONT></TT><EM>// ...</EM><TT><BR><FONT
face=新宋体> } </FONT></TT></DIV>
<P>有些人不喜欢<TT><FONT
face=新宋体>operator</FONT></TT>关键字或类体内的有些古怪的语法。但是算符重载语法不是被期望用来使得类的开发者的工作更简易。它被期望用来使得类的用户的工作更简易:
<P>
<DIV class=CodeBlock><TT><FONT
face=新宋体> int main()<BR> {<BR> Array a;<BR> a[3] = 4; </FONT></TT><EM>// 用户代码应该明显而且易懂...</EM><TT><BR><FONT
face=新宋体> } </FONT></TT></DIV>
<P>记住:在一个面向重用的世界中,使用你的类的人有很多,而建造它的人只有一个(你自己);因此你做任何事都应该照顾多数而不是少数。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/friends.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[13.5]></A>
<DIV class=FaqTitle>
<H3>[13.5] 什么算符能/不能被重载?</H3></DIV>
<P>大多数都可以被重载。C的算符中只有 <FONT face=新宋体><TT>.</TT><TT> </TT></FONT>和 <TT><FONT
face=新宋体>? :</FONT></TT>(以及<TT><FONT
face=新宋体>sizeof</FONT></TT>,技术上可以看作一个算符)。C++增加了一些自己的算符,除了<TT><FONT
face=新宋体>::</FONT></TT>和<TT><FONT face=新宋体>.*</FONT></TT>,大多数都可以被重载。
<P>这是一个下标算符的示例(它返回一个引用)。先没有算符重载:
<P>
<DIV class=CodeBlock><TT><FONT
face=新宋体> class Array {<BR> public:<BR> int& elem(unsigned i) { if (i > 99) error(); return data[i]; }<BR> private:<BR> int data[100];<BR> };<BR> <BR> int main()<BR> {<BR> Array a;<BR> a.elem(10) = 42;<BR> a.elem(12) += a.elem(13);<BR> }
</FONT></TT></DIV>
<P>现在用算符重载给出同样的逻辑:
<P>
<DIV class=CodeBlock><TT><FONT
face=新宋体> class Array {<BR> public:<BR> int& operator[] (unsigned i) { if (i > 99) error(); return data[i]; }<BR> private:<BR> int data[100];<BR> };<BR> <BR> int main()<BR> {<BR> Array a;<BR> a[10] = 42;<BR> a[12] += a[13];<BR> }
</FONT></TT></DIV>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/friends.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[13.6]></A>
<DIV class=FaqTitle>
<H3>[13.6] 我能重载 <TT><FONT face=新宋体>operator==</FONT></TT> 以便比较两个 <TT><FONT
face=新宋体>char[]</FONT></TT> 来进行字符串比较吗?<IMG alt=UPDATED!
src="C++ FAQ Lite[13]--算符重载(新).files/updated.gif"></H3></DIV><SMALL><EM>[Recently
changed so it uses the <TT><FONT face=新宋体>std::</FONT></TT> syntax (on 7/00). <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#[13.8]">Click
here to go to the next FAQ in the "chain" of recent changes<!--rawtext:[13.8]:rawtext--></A>.]</EM></SMALL>
<P>不行:被重载的算符,至少一个操作数必须是用户定义类型(大多数时候是类)。
<P>但即使C++允许,也不要这样做。因为<A
href="http://www.sunistudio.com/cppfaq/exceptions.html#[17.5]">在此处你应该使用类似
<TT><FONT face=新宋体>std::string</FONT></TT>的类而不是字符数组</A>,因为<A
href="http://www.sunistudio.com/cppfaq/containers-and-templates.html#[31.1]">数组是有害的</A>。因此无论如何你都不会想那样做的。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Previous section</A>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -