C++运算符重载需要注意的地方

上一篇 / 下一篇  2012-08-30 13:28:15 / 个人分类:C++

t1bFg#@ I"j+k8S0  有时候自己写一个类,需要重载运算符,但对于一些操作符(如==、<、>等),可以在类里写,也可以在类外写。那么 C++ 编译器会去怎么调用呢?

)b#E"f Q;h,X0 51Testing软件测试网h-y b'O+IH1N^3P

  首先,我们知道,“重载” 机制可以允许多个函数有相同的函数名,但参数列表必须不同。C++编译器经过名字改编(name mangling),可以在调用时依据所传实参找到“最符合”的函数实体进行调用。而运算符重载亦是如此。51Testing软件测试网2e$M xi-|

pY;sL/z4U0  首先,我们有一个类:

i I+s$E#Ql#M*_ssa0

Hxi1|!Q1h~Fb\L0

}6_M%u gp6jr"z0
51Testing软件测试网*j$Q+{,oo;E)?Z

class CMyCls51Testing软件测试网/fa.~%U|xP ]*|:|,B
{
t&Od-U;S(},Vh0public:
lK s[;S,L0 bool perator == (const CMyCls& rhs);    // 1.51Testing软件测试网omn\lo}IF
 51Testing软件测试网;b#o(d$x/I1e{0BN
 bool perator == (const CMyCls& rhs) const;   // 2.

#dM+M4FF1n%@0 51Testing软件测试网]&`-]B@eu,~B X

 bool perator == (CMyCls& rhs);      // 3.

|f7su5t0

jl)u@ @.O N TmE0n0 bool perator == (CMyCls& rhs) const;    // 4.51Testing软件测试网_ vVf7p.{1wb!ef
};
51Testing软件测试网m2[8G2E8`Gc ^j

m;x(|.S7|0
'Bf%g`-pN w0void f1 (CMyCls& lhs, const CMyCls& rhs);
uq"x G M0{
FC sk7n T'x0GC0 lhs == rhs;
Y^ zWj0}

YK1J d+[:]:B;Eg ]0

&U)`z:jI~(FS!dNT0void f2 (const CMyCls& lhs, const CMyCls& rhs);
Kw1H^K"U{)~,^v0{
z`k0W9N:D v"m0 lhs == rhs;51Testing软件测试网 e G*poZ?UL
}

C-m"J$~q t?q0

!Q$b(IMt&qn"t0void f3 (CMyCls& lhs, CMyCls& rhs);51Testing软件测试网*h,btf;bD){n
{
$_W|%H N0 lhs == rhs;
xZnS ]4E#W0}

%G TF9y$y!]0 51Testing软件测试网7U;B%uxZV T

void f4 (const CMyCls& lhs, CMyCls& rhs)51Testing软件测试网B I$p LGw0DP]
{
zMB%pM]0 lhs == rhs;51Testing软件测试网 A Y"V3tu_I
}

3kN#Hq3E%s e_0

s-c3v^j(n%j0  那么 f1 - f4 这四个函数将会如何调用呢?其实,f1函数会调到CMyCls类中1 处注释所标的函数,f2会调到 2 处注释所标的函数,f3、f4依次类推。

$[g,}2QU0

FN,GC.n,d _b/v0  那么,如果我在类里面有一个运算符重载,在类外也有,会调用哪一个呢?比如:

e{1yZeQc(E!I0

9ZI.C*P*q1o%?0 51Testing软件测试网2lb] X1N&`c;y]

8?(SP'G E(uMu0class CMyCls51Testing软件测试网zF`Ee
{
;sY L7R#\ dq#bE0public:51Testing软件测试网0]Ye GB9x^l
 bool perator == (const CMyCls& rhs) const51Testing软件测试网 y!sG\[]1|a%T
 {
,n)B?d jm i@0  // ...51Testing软件测试网+t.G/h&l8D*D
 }51Testing软件测试网5Kvf8aWbT)s
};

XlO)Rm0

0v-T-LzoK C0
mbI)|!R} gc^:^N0bool perator == (const CMyCls& lhs, const CMyCls& rhs)51Testing软件测试网;dN?^ k5C!x@q
{
4_K-B+`,Y(I%U1}W0 // ...51Testing软件测试网s hm*D*UN V2u*u
}

%TVE3O'Qw+Z0

@MZS4nk0
y5Y2pv U5H_+DE @T"L0void f(const CMyCls& lhs, const CMyCls& rhs)
e4w?V)R0{51Testing软件测试网j6w8@#Jz@6{
 lhs == rhs;51Testing软件测试网~ [0Y&fX M0L(~2N!|o
}

F\+Ni,X)u;R-`0

1QBQ {(mPC0|0  但很不幸的是,这样编不过。因为对于 f 函数的调用来说,编译器不知道调哪一个会比较好,因为同时存在两份“最适合”的重载函数,所以产生歧义。但这样是可以编过的,思考下为什么:

:{Y{ul ~+]g3v0 51Testing软件测试网P'o*^L ac ~

Qg|s"v8J*T0
51Testing软件测试网){E"V;h)SWV9J

class CMyCls
"s.a~gk#lk OI0{
G`4og&Q.eu&o8@0public:51Testing软件测试网Gcr ]H'w
 bool perator == (const CMyCls& rhs)
6vv]8T(r3Y*{5w:y0 {
,k7g3r1^^;JPR0  // ...51Testing软件测试网9gCX Fb9[b
 }51Testing软件测试网 o g2Q-tZu.A5U e0m
};

OUuo k)Bvp0 51Testing软件测试网3iY:ptP|C0| h


A$OH0]6t\0bool perator == (const CMyCls& lhs, const CMyCls& rhs)51Testing软件测试网iEqd.WX
{51Testing软件测试网P!DIZq
 // ...
4Z:x$X.~8]0}

nu!V] iP-F8D)f@0

vHxkh!Nn051Testing软件测试网)^XVU$B
void f1(const CMyCls& lhs, const CMyCls& rhs)51Testing软件测试网 S)D#[j$Q)n
{
x@ h~)b*v0 lhs == rhs;51Testing软件测试网2N5s)PC Z[8N$T
}
51Testing软件测试网-oL:X U0r

iFX%k%bWpL$Ci051Testing软件测试网%m2sZ3|l0GJv6RV,N
void f2(CMyCls& lhs, const CMyCls& rhs)51Testing软件测试网 iXj\p_x%r
{
(q W4u({X+J0K.B0 lhs == rhs;51Testing软件测试网es+LG6UF'D|7L)n
}

[5D%kAq$Dj2Y.}0

Db;~ ]o4[#a!l*Aj0  上面 f1会调到全局的函数operator ==,而f2会调到 CMyCls的成员函数operator ==。所以,最好的写法是只在类里或类外重载两个参数均为const的版本。51Testing软件测试网'tWq'eKZ


TAG:

 

评分:0

我来说两句

Open Toolbar