在重载postfix运算符时,我无法理解操作的顺序。让我们来看看下面的两个小例子:
int i = 0;
std::cout << std::endl << "i: " << i;
i = ++i;
std::cout << std::endl << "i: " << i;
i = i++;
std::cout << std::endl << "i: " << i;
MyClass myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = ++myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = myObject++;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
出现两种截然不同的行为。输出如下:
i: 0
i: 1
i: 2
myObject: 0
myObject: 1
myObject: 1
你看,不同的行为。这是我的重载操作符方法的概述。
MyClass & MyClass::operator++ ()
{
++myValue;
return *this;
}
MyClass MyClass::operator++ (int postfixFlag)
{
MyClass myTemp(*this);
++myValue;
return myTemp;
}
好的。前缀很有意义。您可以增加所需的任何内容,然后返回相同的对象,现在已修改,以便分配。但后缀是什么让我沮丧。它应该分配,然后增加。在这里,我们是自我分配。因此,使用内置整数类型,它是有道理的。我将i
的值分配给自己,然后i
递增。很公平。但是,让我们说MyClass
是对int的重新创造。它从0开始,获得前缀递增,然后变为1.然后,关键行。 myObject = myObject++
。这跟myObject = myObject.operator++(int postfixFlag)
是一回事。它被调用。 myTemp
初始化为值1.它增加到2.然后我们返回临时值。如果我们分配给另一个对象,这是有效的。但是在这里我是自我分配的,所以在增加到2之后,myObject
被设置为等于用初始值初始化的返回临时对象,我们又回到了1!那讲得通。但这是一种根本不同的行为。
我该如何解决? int怎么做?这个方法一般是怎么写的?您对C ++行为和设计有何评论?等等我现在有点困惑,因为书籍和在线例子似乎总是使用上述方法的变体。
感谢阅读,任何意见都将不胜感激!
答案 0 :(得分:5)
正如其他人所说,对于int,行为是未定义的。但我想我会试着解释为什么你的MyClass它永远不会达到2。
诀窍是你在后缀版本中采取以下三个步骤:
this
的{{1}}副本(myTemp
)。myValue == 1
(所以this->myValue
; myTemp.myValue == 1
)。this->myValue == 2
(myTemp
)。因此,您要修改myValue == 1
,但调用this
的代码永远不会再次看到myObject++
。它只会查看返回的值,它是旧 this
的副本。
operator ++的代码很好。问题是你如何使用它 - 你不应该将预增量或后增量的结果写回同一个变量(行为是未定义的)。以下是一些可能更有启发性的代码:
myObject
打印:
int i = 0;
std::cout << "i: " << i << std::endl;
int j = ++i;
std::cout << "i: " << i << ", j: " << j << std::endl;
int k = i++;
std::cout << "i: " << i << ", k: " << k << std::endl;
MyClass myObject;
std::cout << "myObject: " << myObject.getMyValue() << std::endl;
MyClass myObject1 = ++myObject;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject1: " << myObject1.getMyValue() << std::endl;
MyClass myObject2 = myObject++;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject2: " << myObject2.getMyValue() << std::endl;
我改变了你的代码,以便不是每次都分配给一个新的变量,而是分配给它自己。请注意,在i: 0
i: 1, j: 1
i: 2, k: 1
myObject: 0
myObject: 1, myObject1: 1
myObject: 2, myObject2: 1
和int
两种情况下,主变量(MyClass
/ i
)都会递增两次。但是,在预增量的情况下,新变量(myObject
/ j
)采用新值,而在后增量情况下,新变量(myObject1
/ { {1}})接受旧值。
编辑:只是回答问题的另一部分,“Int怎么做?”我假设这个问题意味着“k
类中的预增量和后增量代码是什么样的,我怎样才能使我的相同?”答案是,没有“myObject2
类”。 int
是C ++中的一种特殊内置类型,编译器会特别对其进行处理。这些类型没有用普通的C ++代码定义,它们被硬编码到编译器中。
注意:对于想要自行尝试的人,以下是问题未包含的int
代码:
int