C++ 为什么要添加++;重载操作的结果是否为未包含的值?

C++ 为什么要添加++;重载操作的结果是否为未包含的值?,c++,C++,参见代码 #include<iostream.h> #include<conio.h> class A{ private: int i; public: A() { i=10; } A operator++(int) { A tmp=*this; i +=1; return tmp; } d

参见代码

#include<iostream.h>
#include<conio.h>
class A{
   private:
      int i;
   public:
      A()
      {
         i=10;
      }
      A operator++(int)
      {
         A tmp=*this;
         i +=1;
         return tmp;  
      }
      display()
      {
         cout<<i;
      }
};
int main()
{
   A a,b;
   b=a++ + a++;
   cout<<endl<<b<<"\t"<<a;
   return 0;
}
#包括
#包括
甲级{
私人:
int i;
公众:
()
{
i=10;
}
运算符++(int)
{
A tmp=*这一点;
i+=1;
返回tmp;
}
显示()
{

cout正如Charles指出的那样,
++
对对象调用的是函数调用。因此,首先将i从10增加到11并返回10,然后在第二次调用中将i从11增加到12并返回11。最后将10和11相加,得到21。

第一次调用将
A增加到11并返回10。第二次调用将增加
a
到12并返回11。听起来21是正确的

也就是说,求值顺序(即
++
是“第一次调用”)是未指定的(感谢JD),因此在同一表达式中使用它两次通常不是一个好主意。

根据,您的代码等于
b=(a+++)+(a++)

因此,计算它,我们有:

a = 10;
tmp1 = a++;//tmp1 = 10, a = 11
tmp2 = a++;//tmp2 = 11, a = 12
b = tmp1 + tmp2 // 10 + 11 = 21

还要记住,像
b=a+++a++;
这样的结构可读性很差,所以你应该始终使用括号,而且在复杂表达式中避免使用像
a++
这样的递增和递减也是一个好主意。可读性比显示你知道运算符优先级要好得多。

我将给出我的答案以简单比较的形式

您的代码是:

b = a++ + a++;
我想你把它和:

b = a + (a++)++;

重载运算符只是具有有趣名称的函数。它们的行为不一定与内置运算符相同。如果您试图对内置类型的对象执行相同的表达式,则该行为将是未定义的

您还没有显示
操作符+
对于
A
的定义-我将判断它是一个自由函数。表达式
b=A+++A++;
可以重写为

b = operator+( a.operator++(0), a.operator++(0) );
希望这能让事情变得更清楚


对postfix increment的两个调用是不确定顺序的-这意味着我们无法知道将首先调用哪一个。在您的情况下,这并不重要,因为它们都是在同一个对象上调用的,但不依赖于任何特定的顺序-即使在程序的同一执行过程中,也不需要保持一致。

请提供一个简短的com请举个例子。你所拥有的不会被编译。你只是在尝试一些东西,还是它在实际的产品代码中意味着什么?如果对于产品代码,我真的希望你不要使用它。这是因为可读性。为什么人们仍然试图理解这些无意义的语句?其中一些语句不是未定义的行为,但仍然是:它们几乎不可读nd-在这种情况下-直觉基本上是错误的。停止它!
不是标准标题。使用
。此示例也没有使用
中的任何内容。“我们认为的预期值将是20”,为什么?我认为这是定义的,因为两个运算符是相同的(
++
)。但这两个
++
都是函数调用。写操作发生在单独函数调用中的单独语句中,因此存在中间的“序列点”,使用旧术语。这不是行为未定义的原因。感谢Charles的解释。请注意,称第一个为未定义。可以是两个中的任何一个。但这不会改变结果。@Guilhermbernal:Pedantry--未定义,但未指定。@Guilhermbernal,如果两者都调用,有什么区别是一样的吗?@cpp:你可以带一辆奥迪去商店,或者一辆自行车去商店。结果是一样的:你在商店……但这并不能改变两辆车不太相似的事实。对。你不能说这是11+10还是10+11。所以你不想在
a++*f(a++)中这样做
例如。