+= 运算符重载和级联是什么?

14

出于教育目的,我希望以级联方式重载和使用 += 运算符。

class a {
    public:
        a();
        a& operator+= (float f);
    private:
        float aa;
}

a() {
    aa = 0;
}

a& operator+= (float f) {
    aa += f;
    return *this;
}

a b;
b += 1.0; // Works.
b += 1.0 += 1.0; // Error : Expression must be a modifiable lvalue.

我不明白为什么上面的代码不起作用(除了可能存在的语法错误——我没有尝试编译这段示例代码)。在重载的operator+=方法中返回*this,我希望第二个+= 1.0 调用b对象,是这样吗?

谢谢。


1
你应该发布没有额外“有趣”的错误的代码,这些错误与你试图说明的问题无关。 - juanchopanza
说实话,我总是做类似于 b += 1.0 + 2.0 的事情。 - IssamTP
运算符优先级。+= 从右向左计算。 - user3072164
3个回答

26
b += 1.0 += 1.0;
+= 的结合性是从右到左的。所以以上内容的解释如下:
(b += (1.0 += 1.0));

这个有意义吗?不。

为了让它起作用,你需要将其写成:

(b += 1.0) += 1.0;
希望这有所帮助。

1
请注意,为了让使用者对于 class a 的使用没有太多的意外,最好也定义一个成员函数。
a& operator+=(a const&); 

除了非成员函数

a operator+(a const&, a const&); 
a operator+(a const&, float); 
a operator+(float, a const&);

每个成员operator+=重载都定义了一个函数。然后,您可以编写:

a1 += b1 + c1; 

其中a1是类型为a的变量,变量b1c1都可以是floata类型。请参阅this question来自获取更多详细信息。


a operator+(a, a const&);a const& 版本更好,不是吗? - Nawaz
@Nawaz 当然可以,但我希望避免在这里讨论整个效率业务和lvalue/rvalue问题,因为您也可以对operator+=进行2个重载,并对所有组合的a&&a const&进行4个operator+的重载。例如,请参见https://github.com/d-frey/operators。我在这里要表达的观点是,“像整数一样做”至少需要几个`a`和`float`的重载以及一个`operator+`来配合单个的`operator+=`。 - TemplateRex

0

补充一下之前的答案。你可能会对转换构造函数和/或转换运算符感兴趣。例如:

class a {
    public:
        a();
        a(float f);
        a& operator+= (float f);
        operator float() const;
    private:
        float aa;
};

a::a() {
    aa = 0;
}

a::a(float f) {
    aa = f;
}

a& a::operator+= (float f) {
    aa += f;
    return *this;
}

a::operator float() const {
    return aa;
}

int main()
{
    a b = 1.0;
    b += 1.0; // Works.
    b += (a)1.0 += 1.0; // Works.
}

或许更好的方法是不使用转换运算符,而是使用 operator+=(const a&);

class a {
    public:
        a();
        a(float f);
        a& operator+= (float f);
        a& operator+= (const a & x);
    private:
        float aa;
};

a::a() {
    aa = 0;
}

a::a(float f) {
    aa = f;
}

a& a::operator+= (float f) {
    aa += f;
    return *this;
}

a& a::operator+= (const a & x) {
    aa += x.aa;
    return *this;
}

int main()
{
    a b = 1.0;
    b += 1.0; // Works.
    b += (a)1.0 += 1.0; // Works.
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接