关于C++重载运算符

DDM*_*DMC 3 c++ operators

在我的电脑上运行以下程序

#include <iostream>

class Int {
public:
  Int(int x) : val{x} {}
  Int operator++() {
    std::cout << "Int::operator++()\n";
    return ++val;
  }
  friend Int operator+(Int a, Int b) {
    std::cout << "operator+(Int, Int)\n";
    return a.val + b.val;
  }
  friend Int operator*(Int a, Int b) {
    std::cout << "operator*(Int, Int)\n";
    return a.val * b.val;
  }

private:
  int val;
};

int main()
{
  Int a = 1, b = 2;
  b = ++a + b * b;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到了这个输出:

operator*(Int, Int)
Int::operator++()
operator+(Int, Int)
Run Code Online (Sandbox Code Playgroud)

据我所知,前缀的++优先级高于二进制*.但是在上面显示的输出中,前缀++是在二进制之后调用的*!是因为编译器将operator +视为函数调用(导致未指定的行为)?我总是可以考虑重载运算符的功能(这使得行为x = x++定义良好时x是Int)?

谢谢!

Rak*_*111 5

是因为编译器将其operator+视为函数调用(导致未指定的行为)?

是.但请注意,如果++a在之后进行评估并不重要b * b,因为最后,正确地添加了这两个,这符合运算符优先级规则.

没有赋值的表达式相当于:

operator+(a.operator++(), operator*(b, b))
Run Code Online (Sandbox Code Playgroud)

函数参数的评估顺序是未指定的,因此从技术上讲,++a可以在之前进行评估b * b,但也可以相反.

我总是可以考虑重载运算符的功能(这使得行为x = x++定义良好时x是Int)?

是的,不是.如果Int与"普通"运算符相同,那么就没有(直到C++ 17),因为这将是未定义的行为.但如果Int不改变x,x++例如,那么是.

  • @LajosArpad因此,不要写这样的代码 (3认同)