二元运算符+,=使用const重载

时间:2015-01-07 14:09:50

标签: c++ operator-overloading

我正在学习C ++概念,并非常感谢任何有关解释的帮助。为什么语句4没有编译,但语句1是。

class X {
    public:
            X& operator= (const X& rhs);
            const X& operator+ (const X& rhs) const;
            const X& operator+ (int m);
    private:
            int n;
};

int main() {
        X a, b, c;
        a = a + 5 + c; //statement 1 - No compiler errors
        a = b + 5; //statement 2
        a = a = b + c; //statement 3
        a = b + c + 5; //statement 4 /*compiler Error thrown -
passing 'const X' as 'this' argument of 'const X& X::operator+(int)' discards qualifiers
 [-fpermissive]*/
        (c = a + a) = b + c; //statement 5
}

根据我的理解(基于:两个+& =是右关联的),上述5个语句被解译为 -

//statement 1
a.operator=(a.operator+(5.operator+(c)));

- >我认为这应该抛出错误,因为没有定义的构造函数支持此

//statement 2
a.operator=(b.operator+(5));

//statement 3 
a.operator=(a.operator=(b.operator+(c)));

//statement 4
a.operator=(b.operator+(c.operator+(5)));

//statement 5
(c.operator=(a.operator+(a)))=(b.operator+(c)); then
lhs_result.operator=(rhs_result);

我是否正确解读了上述第5条声明?

4 个答案:

答案 0 :(得分:3)

如果你想要编译4语句,那么声明运算符

const X& operator+ (int m) const;

问题在于本声明

a = b + c + 5;

b + c是一个const对象。请参阅相应的运算符声明

        const X& operator+ (const X& rhs) const;

您可能不会为const对象调用非const成员函数。

从左到右考虑添加剂操作员+组。 来自C ++标准(5.7添加运算符)

  

1加法运算符+和 - 从左到右分组。

至于声明5

(c = a + a) = b + c; //statement 5

然后它具有未定义的行为,因为赋值运算符的操作数的计算未按顺序排序。 因此,首先表达式(c = a + a)将被评估,然后表达式b + c。 或者首先评估表达式b + c,然后只计算表达式(c = a + a)

答案 1 :(得分:0)

编译器错误

a = b + c + 5;

您的operator +(int m)未标记为const。这就是编译器错误告诉你的。您还应该只返回X,因为+计算新的X值。

X operator+ (int m) const;    

将解决这个问题。

运营商关联性

只有operator =是右关联的。 http://en.cppreference.com/w/cpp/language/operator_precedence

评估顺序

  1. 您的陈述1

    a.operator =(a.operator +(5.operator +(C)));

  2.   

    我认为这应该抛出错误,因为没有定义的构造函数支持这个

    此处不涉及构造函数。

    1. 声明4

      a.operator =(b.operator +(c.operator +(5)));
      应该是

      a.operator =(b.operator +(C)+ .operator(5))

    2. 声明5

      (c = a + a)= b + c;
      由于赋值位于括号内,因此优先于关联性。即在c = a + a之前评估= b + c

      (c.operator =(a.operator +(a)).operator =(b.operator +(c))

答案 2 :(得分:0)

声明1执行此操作:

a.operator+(5).operator+(c)

这很有效,因为operator+ X constconst,因此适用a.operator+(5)返回的b.operator+(c).operator+(5) 临时值。

声明4这样做:

operator+

这不起作用,因为int的{​​{1}}不是const,因此对const临时返回的b.operator+(c)不起作用1}}。

两个operator+都需要const来完成这项工作:

X operator+(const X& rhs) const;
X operator+(const int& m) const;

注意我还将运算符更改为按值而不是按引用返回。它应该是这样的(毕竟两个数字相加的结果是一个新数字。)

答案 3 :(得分:0)

声明一相当于a.operator=(a.operator+(5).operator+(c)); 所以这完全有效。

但是对于语句4,operator+ (int m)方法必须是const。含义:const X& operator+ (int m) const;

声明5应相当于:c.operator=(a.operator+(a)).operator=(b.operator+(c));

编译代码时clang的错误和警告非常有用,我建议将其用于此类实验。它的错误和警告信息非常好:

test.cpp:15:13: error: invalid operands to binary expression ('const X' and 'int')
  a = b + c + 5; //statement 4 /*compiler Error thrown -
      ~~~~~ ^ ~
test.cpp:4:12: note: candidate function not viable: no known conversion from 'int' to 'const X' for 1st
      argument
  const X& operator+ (const X& rhs) const;
           ^
test.cpp:5:12: note: candidate function not viable: 'this' argument has type 'const X', but method is not
      marked const
  const X& operator+ (int m);
           ^
1 error generated.