6重载赋值运算符“=”
/ t" @9 G9 W3 C+ e4 W9 Y4 ` 赋值运算符只能作为成员函数重载。 1 w s' m# z$ R
常见的真正需要重载赋值运算符的情况是:类中包含指向动态空间的指针
$ ]6 ]6 c1 A3 {5 b- V5 j- h 赋值运算符=的重载应注意以下几点:
) ]5 w5 ~9 S5 ~" U( c. b ①返回值声明为引用,而函数体中总是用语句return *this;返回; ; W% \( j- @0 s0 s
②如果参数被声明为指向同类对象的引用或指针,应判别所指向对象的是否与被赋值对象为同一对象,如果是,立即返回,不做任何赋值处理;
- o' v i( w" U9 A/ p( Y ③如果被赋值对象占用了动态空间或其他资源,应首先释放这些资源,以便接收新的资源; ( D( x: K" _2 u9 R7 { r
④如果参数被声明为指针或引用,通常应加上const修饰;
: {# g, x3 ~# z* [ ⑤如果参数被声明为指针,应判别是否为空,以便做出特殊处理; & j7 @; W2 p1 s
⑥一个类如果需要重载运算符=,通常也就需要定义自己特有的拷贝构造函数,反之亦然。 5 E2 Q5 t! c& }4 U3 M3 J
7重载复合赋值运算符“+=”
) }! n* P5 C# k( Z2 Y3 m8 n 重载复合赋值类运算符,如+=、-=等,也应遵循上述重载赋值运算符的注意事项。 " ? R$ k$ `$ l+ e7 S8 t# e9 n
与赋值运算符不同的是,复合赋值类运算符既可作为成员函数重载也可作为非成员函数重载。在后一种情况下,两个操作数都必须出现在参数表中;为了保持运算符原有的特性,第一参数应当声明为引用(否则就无法改变它的值),返回值也应当像重载“=”那样声明为引用,并在最后将获得新值的第一参数返回。 ) A3 ?" e" p5 w( H; ?. {5 N6 P
8重载关系操作符“>”
$ I* x- V {7 p/ V1 Z 重载的关系操作符函数应返回逻辑值。对于 fraction的两个对象,可以通过比较通分后的两个分子来确定它们的大小。为此,可在fraction.h的类声明中增加如下的成员函数声明:
8 C9 z \% f2 \! W0 @% u bool operator>(fraction f){ return num*f.den>f.num*den;} - U( i9 ~. v7 Z! a( a( q1 b
其他关系运算符可以参照重载。
# S C1 u0 u0 o9 f2 a, }; X! c 9重载下标访问运算符“[ ]”
% D" P0 } J/ i+ c% g1 H 运算符[ ]只能作为成员函数重载。 ' _2 `7 {: ?4 S6 K9 l
10重载C+ +流运算符“”和“”
7 C; P4 W3 D* x4 p% I& M C+ +流的输入运算符和输出运算符只能作为非类成员函数重载。在一个类中,如有必要,可将或声明为友元函数。
6 ~' y8 k8 S3 B 8.3 运算符重载应注意的几个问题 * ^7 B2 |: N8 h& L0 m/ d
1重载的运算符应保持其原有的基本语义
4 w: u3 Q4 C7 Z9 Z) q4 Z+ h 重载的运算符应该体现为原运算符的功能在新的数据类型上的延伸,它的使用应当使程序中算法的表达显得更流畅、自然,使阅读程序的人在不借助于其他说明资料的情况下就能够正确理解。不要让重载的运算符去勉强承担那些更适于一般函数承担的功能。 2 \2 C) p$ s: \. ]) |# Y& g
2.生载的运算符应尽可能保持基原有的特性 & N7 d9 p1 r" p) h
运算符的操作数个数、优先级和结合性是三个最基本的特性,而且是重载时自然得以保持的特性,因此无须采取专门的措施。需要注意的是下面这些特性。
6 {* G. L; E5 Y4 k ①是否要求第一操作数为有左值操作数。 " W- w/ p5 Z% ?7 X7 ^
②是否修改第一操作数。
4 _7 a3 r- v1 q2 L2 p ③操作的结果是否为有左值数据。
4 ?6 | @, e1 r ④应保证第二操作数不被改变。
: v: \8 @4 G8 {* C5 V 3运算符的重载应当配套
/ Q4 t& a* o) ~$ c7 _0 Z* O7 ? 某些运算符之间关系密切,存在着某种逻辑上的联系,因此若需要重载其中的某一个,往往就意味着同组的其他运算符也需要重载。 . Q8 H/ a {# I/ u, |
4使用引用参数还是非引用参数? i8 X$ {( O6 l+ M
非引用参数的优点是:以传值方式传递参数,形参变量只是实参的副本,对形参变量的修改不会影响实参;在相关对象存在只需一个实参的构造函数的情况下,可以充分利用表达式处理过程中的自动转换机制,使表达式显得更自然。但当对象很大或需要深层复制时,非引用参数占用的计算机资源较多,影响参数传递的效率。
6 B( y- ?6 T, [/ h+ ]( \4 Y u 引用参数的优点是:当对象很大或需要深层复制时,可大大减少对资源的占用,提高参数传递的效率。但无法利用系统的自动转换机制。
2 m8 f! r, q" s4 {" Q* v3 w: K7 y, q: D 5作为成员函数重载还是作为非成员函数重载? =、[ ]、()、->以及所有的类型转换运算符只能作为成员函数重载。如果允许第一操作数不是同类对象,而是其他数据类型,则只能作为非成员函数重开车(如输入输出流运算符和就是这样的情况)。若希望系统在必要时能够利用只需一个实参的构造函数自动对第一操作数进行转换,也应将该运算符作为非成员函数重载;此种情况下,运算符函数的参数应该是非引用参数,否则不能达到所希望的效果。其他情况下一般应作为成员函数重载。 |