我有以下代码:
class Array
{
public:
int aaa;
Array():aaa(1){}
void print()
{
cout << aaa << endl;
}
Array& operator++()
{
aaa++;
return *this;
}
Array operator++(int)
{
Array a(*this);
aaa++;
return a;
}
};
我有一些问题如下:
为什么prefix返回一个引用,postfix返回一个对象?在C ++ Primer一书中,作者只解释了“For consistency with the built-in operators
”。
然后,我测试了代码:
数组ar;
(ar++).print(); // print 1
ar.print(); // print 2
输出正是我的预期。 现在我将重载后缀函数中的代码更改为:
Array operator++(int)
{
Array a(*this);
a.aaa++; // changed this
return a;
}
我打电话给测试代码:
Array ar;
(ar++).print(); // this prints 2
ar.print(); // this prints 1
为什么我得到这样的结果?
答案 0 :(得分:3)
后缀运算符返回一个对象,而不是引用,因为它必须返回当前对象的未更改版本;它必须在增量完成之前返回值。因此,必须分配新对象。如果您返回了引用,那么引用将是什么?
在你的第二个例子中,你正在创建一个新对象,递增它并返回它,但是你没有改变运算符应用到的原始对象 - 这显然是错误的,所以给出了错误的结果。
答案 1 :(得分:0)
虽然前缀和后缀运算符在直观上似乎 mutate 调用它们的对象,但它们实际上具有不同的语义含义。前缀运算符接受一个对象,对其应用递增操作,并返回相同的对象。后缀运算符获取一个对象,复制它,将增量运算符应用于原点,然后返回副本。
正是由于这个原因,您可能已经看到各种消息来源阻止使用后缀运算符 - 因为后缀副本创建了一个临时对象,它可能效率低于前缀运算符。对于必须维护大量状态信息的对象,使用后缀运算符可能很昂贵。