C++ 运算符 += 重载返回引用

c++ operator += overloading return reference to

本文关键字:返回 引用 重载 运算符 C++      更新时间:2023-10-16

有人可以解释一下这个运算符重载示例中的区别是什么,Average& operator+=(int num)返回对Average的引用与不返回对Average的引用,即Average operator+=(int num).

返回引用是否意味着返回对被分配到的对象(而不是副本)的引用,该对象*this。因此,在这种情况下,返回对对象avg的引用。

非参考版本如何/为什么工作?结果被复制到哪里?

#include <iostream>
#include <cstdint> // for fixed width integers
class Average
{
private:
int32_t m_total = 0; // the sum of all numbers we've seen so far
int8_t m_numbers = 0; // the count of numbers we've seen so far
public:
Average()
{
}
friend std::ostream& operator<<(std::ostream &out, const Average &average)
{
// Our average is the sum of the numbers we've seen divided by the count of the numbers we've seen
// We need to remember to do a floating point division here, not an integer division
out << static_cast<double>(average.m_total) / average.m_numbers;
return out;
}
// Because operator+= modifies its left operand, we'll write it as a member
Average& operator+=(int num)
{
// Increment our total by the new number
m_total += num;
// And increase the count by 1
++m_numbers;
// return *this in case someone wants to chain +='s together
return *this;
}
};
int main()
{
Average avg;
avg += 4;
std::cout << avg << 'n';

return 0;
}

你应该返回一个引用,因为这是标准库中大多数代码使用的约定,大多数程序员都这样做。大多数程序员会期望以下代码:

std::string s;
(s += "a") = "b";
std::cout << s << std::endl;

打印b,或在此示例中:

int n = 10;
(n += 20) = 100;
std::cout << n << std::endl;

将期望打印100

这就是为什么你应该返回一个引用以保持约定,该约定允许修改位于赋值左侧的对象。

否则,如果您按值(副本)返回赋值,如上例所示将分配给临时。

在 C++ 中重写运算符时,可以以多种形式提供它们。您可以定义不返回对已修改对象的引用的赋值运算符,它们将按预期工作。但是,对于每个运算符,我们都有所谓的规范实现:

除了上述限制之外,该语言对重载运算符的操作或返回类型(它不参与重载解析)没有其他约束,但通常,重载运算符的行为应尽可能类似于内置运算符:operator+期望添加而不是乘以其参数,operator=应分配等。相关运算符的行为应该类似(operator+并且operator+=执行相同的类似加法的操作)。返回类型受到预期使用运算符的表达式的限制:例如,赋值运算符通过引用返回以使其可以写入a = b = c = d,因为内置运算符允许这样做。

通常重载运算符具有以下典型的规范形式。

关于这些规范形式有很多东西要读,但我建议从这个非常好的 SO 答案开始 运算符重载的基本规则和习语是什么?


非参考版本如何/为什么工作?

因为即使C++标准鼓励您使用规范形式,它也不会禁止您不使用规范形式。

结果被复制到哪里?

无处可去,该值将被丢弃。实施可能会优化它们。

返回引用是否意味着返回对被分配到的对象(而不是副本)的引用,即 *this。因此,在本例中返回对对象 avg 的引用。

是的。

非参考版本如何/为什么工作?结果被复制到哪里?

返回值是传递给std::cout <<的临时对象。

这类似于使用:

int foo()
{
return 10;
}
std::cout << foo() << std::endl;

foo的返回值是传递给std::cout <<的临时对象。

尝试检查这个类似的问题。

当您返回引用时,您实际上是在传递实际对象。而当您按值返回时,将创建临时对象,然后将其传递给调用方。

因此,如果您在没有引用的情况下返回,则此分配可能会按照上面的代码段工作。

Average aa = avg += 4;

但是如果你尝试,它将无法编译。

Average *ptr = &(avg += 4);

如果您返回引用,上面的代码将起作用,因为我们正在传递有效的对象范围。