【问题标题】:const return type in operator overloading运算符重载中的 const 返回类型
【发布时间】:2014-03-12 17:10:29
【问题描述】:
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

【问题讨论】:

  • 不再推荐第一个const
  • 由于没有提到,你通常应该通过调用operator/=来实现operator/

标签: c++ operator-overloading constants


【解决方案1】:

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

这是过时的建议,旨在使运算符的行为有点像内置运算符,这样(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

【讨论】:

  • 你能在你的回答中解释一下(b)吗?
  • @debonair:好的,我添加了一些尝试将运算符应用于常量和临时值的示例。
  • @MikeSeymour:“但是,从 C++11 开始,它还禁止移动语义,这会损害效率;因此您不应该返回 const 值。”你能解释一下这条线吗?
【解决方案2】:

对于 binary 运算符,我更喜欢定义一个“免费”(非成员)函数(可能是它所操作的类的 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); 
}

【讨论】:

    猜你喜欢
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2012-04-26
    相关资源
    最近更新 更多