我一直在查看一些开源代码,我看到了重载运算符的两种不同定义。它们之间有什么区别,这样做有什么好处吗?
例如,我们有一个类的一个例子:
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;
}
答案 0 :(得分:3)
一个重载是成员函数,而另一个是自由函数。
使用自由函数以提供混合模式算术。例如: -
foo f;
2 + f; __1
__ 1只有在有自由函数operator+
时才会编译。在这种情况下,成员函数operator+
将不会执行任何操作。
答案 1 :(得分:0)
从外部角度来看,foo::operator+(const foo&)
和::operaor+(const foo&, const foo&)
在置于两个+
- s之间时,使foo
符号具有完全相同的作用。特别是第一个就像第二个,当它自己的fisrt参数是*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+k
和k+a
呢?
对于a+k
,您可以有foo::operator+(int)
或::operator+(const foo&, int)
,但对于k + a,您需要::operator+(int, const foo&)
,因为无法+
作为int
的理解。
所有这一切,你宣言和实施看起来"模糊" (或至少语无伦次):
const foo foo::operator+(const foo& input_foo) {
foo_value += input_foo.foo_value;
return *this;
}
当您撰写c = a+b
时,您是否希望a
的价值发生变化?
你在这里做的是将b
添加到a
并创建a
的副本(为什么const?它毕竟是副本,你已经改变了{ {1}})然后您分配给a
。
操作员+应创建一个新值,其值为总和
foo foo :: operator +(const foo& rop)const //注意签名,使其与decalration保持一致 { foo tmp; tmp.foo_value = foo_value + rop.foo_value; 返回tmp; }
它不是返回类型,而是成员函数本身为c
,作为参数(如果通过引用给出),以便确保const
a+b
a
}}或b
已更改。返回类型只是一个普通值,您可以让调用者按照自己的意愿处理,因为它返回到自己的堆栈框架中。