2015-01-06 28 views
0

我一直在看一些开源代码,我看到两种不同的重载操作符的定义。它们之间的区别是什么?是否有任何好处?这两种操作符重载有什么区别?

例如,一个例子中,我们有一个类:

class foo{ 
public: 
    void SetValue(double input_value) {foo_value = input_value}; 
    double GetValue() {return foo_value;} 
private: 
    double foo_value; 
}; 

然后我有时会看到两种不同类型/样式重载加法运算符(例如)

class foo{ 
    const foo operator+(const foo& input_foo); 
}; 

const foo foo::operator+(const foo& input_foo) { 
    foo_value += input_foo.foo_value; 
    return *this; 
} 

另一种类型的的超载我有时看到的是:

class foo{ 
    friend const foo operator+(const foo& input_foo1, const foo& input_foo2); 
}; 

const foo operator+(const foo& input_foo1, const foo& input_foo2); // Defined right after class 

const foo operator+(const foo& input_foo1, const foo& input_foo2) { 
    foo temp_foo; 
    temp_foo.SetValue(input_foo1.GetValue() + input_foo2.GetValue()); 
    return temp_foo; 
} 
+4

您的第一个版本的operator +'是完全错误的。 –

+1

[运算符重载]的可能重复(http://stackoverflow.com/questions/4421706/operator-overloading) – nbro

+0

您通常将它们定义为具有两个参数的类外方法。一方面,它表明它们不是该类的基本组成部分,但只使用其公共API,另一方面,如果左侧不是您的类(但是例如int),它也可以工作。 – dascandy

回答

3

一个重载是成员函数而其他是免费的功能。

您可以使用自由函数来提供混合模式算术。例如: -

foo f; 
2 + f; __1 

__1只有在有自由功能operator+时才会编译。会员功能operator+在这种情况下不会做任何事情。

+0

'免费功能'? – nbro

+0

@Rinzler非成员函数。 – 0x499602D2

+0

@ 0x499602D2为什么要发明新的名字,如果真名是'friend function',不是? – nbro

0

从外部的角度来看,foo::operator+(const foo&)::operaor+(const foo&, const foo&)在使两个foo-s之间的符号有意义时使+符号具有完全相同的作用。特别是当第一个参数是*this时,第一个就像第二个参数一样。

从内部的角度来看,它们可以在foo类中具有不同的功能:::operaor+(const foo&, const foo&)是一个“自由函数”(一个在全局级声明的函数):它在处理参数时具有对称性的美以同样的方式,但不能访问foo的私有数据成员,除非foo本身不会将其识别为它自己的firend

foo::operator+(const foo&)作为成员函数可以自由访问所有foo成员和数据,但作为foo的成员不太适合“通用算法”(可能更喜欢函数形式)。

也有关于可能的变种其他一些差别:考虑

foo a; 
foo b; 
int k; 

无论是operator+上面看可以赋予意义a+b,但对于a+kk+a

对于a+k你可以有foo::operator+(int)::operator+(const foo&, int),但K + A,你需要::operator+(int, const foo&),因为没有办法有+int一个meber。

所有这一切说,你声明和实现看“模糊”(或至少语无伦次):

const foo foo::operator+(const foo& input_foo) { 
    foo_value += input_foo.foo_value; 
    return *this; 
} 

当你写c = a+b你期望的a值改变?

你做什么,在这里,被添加到ba创建a复印件(常量为什么?这是一个副本毕竟,你已经改变了a)然后分配给c

运营商+应创建一个新的对象,其值之和

富:: foo的运营商+(常量富& ROP)常量//注签名,使它连贯与decalration { 富TMP; tmp.foo_value = foo_value + rop.foo_value; return tmp; }

这不是返回类型,但成员函数本身是const,作为参数,如果通过参考给出,这样就确保a+b既不ab改变。返回类型只是一个普通的值,你可以让你的调用者根据需要对待它,因为它返回到他自己的栈帧。