这两种类型的运算符重载有什么区别

What is the difference in these two types of operator overloads?

本文关键字:什么 区别 重载 运算符 两种 类型      更新时间:2023-10-16

我一直在看一些开源代码,我看到了重载运算符的两种不同定义。它们之间有什么区别,这样做有什么好处吗?

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

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;
}

一个重载是成员函数,而另一个是自由函数。

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

foo f;
2 + f;    __1

__1 只有在有自由函数 operator+ 时才编译。在这种情况下,成员函数operator+不会执行任何操作。

从外部的角度来看,当放置在两个foo -s之间时,foo::operator+(const foo&)::operaor+(const foo&, const foo&)在使+符号有意义方面起着完全相同的作用。 特别是第一个就像第二个,当它自己的第一个参数被*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的价值会改变吗?

在这里,您要做的是将b添加到a并创建a的副本(为什么是const?毕竟它是一个副本,并且您已经更改了a),然后分配给c

运算符 + 应创建一个新对象,其值为 总和

foo foo:

:operator+(const foo& rop) const//注意签名,使其与标注一致{ 傅兜; tmp.foo_value = foo_value + rop.foo_value; 返回 TMP;}

它不是返回类型,而是要const的成员函数本身,如果通过引用给出参数,以便您确保a+b既不更改a也不更改b。返回类型只是一个普通值,您可以让调用者随心所欲地处理,因为它返回到他自己的堆栈帧中。