const返回类型在运算符重载中

时间:2014-03-12 17:10:30

标签: c++ operator-overloading const

const Byte operator/(const Byte& right) const {
    require(right.b != 0, "divide by zero"); 
    return Byte(b / right.b); 
} 

我读到如果运算符的效果是产生一个新值,则需要生成一个新对象作为返回值。例如,Integer::operator+必须生成一个Integer对象,它是操作数的总和。此对象按值const返回,因此无法将结果修改为左值

如果我们不将其写为const怎么办?任何有解释的例子都会有所帮助。

为什么我们在函数原型中有第二个const

2 个答案:

答案 0 :(得分:5)

  

任何有解释的例子都会有所帮助。

这是过时的建议,旨在使操作员的行为有点像内置操作符,以便像(a / b) = c这样的废话不会编译。

但是,从C ++ 11开始,它也会抑制移动语义,这会影响效率;所以你不应该返回const值。

  

为什么我们在函数原型中有第二个const?

参数是const引用,成员函数是const,以(a)确保运算符不修改任一操作数; (b)允许用恒定或临时操作数调用它。

详细说明(b),如果没有这些const限定符,你将无法使用常量操作数:

const Byte a, b;
a / b;  // ERROR: operands can't be const

或临时值:

Byte f();
f() / f();  // ERROR: operands can't be temporary

答案 1 :(得分:1)

对于二进制运算符,我更喜欢定义一个“自由”(非成员)函数(可能是它所运行的类的friend,以备它需要时直接访问该类的privateprotected数据成员:

class Byte {
  ....

    friend Byte operator/(const Byte& left, const Byte& right) {
        require(right.b != 0, "divide by zero"); 
        return Byte(left.b / right.b); 
    }
};

leftright参数均由const &传递,因为:

  • 他们是只读输入参数,因此请将其标记为const
  • 你不想做无用的深拷贝(假设它们不便宜),所以使用参考&

无论如何,如果您的Byte类只包含一个8位字节,并且复制构造函数是一个简单的单字节副本,那么您可以简化代码并只是按值传递

friend Byte operator/(Byte left, Byte right) {
    require(right.b != 0, "divide by zero"); 
    return Byte(left.b / right.b); 
}