我看到这个C ++代码是一个更大的例子的一部分:
Date &Date::operator++()
{
helpIncrement();
return *this;
}
Date Date::operator++( int )
{
Date temp = *this;
helpIncrement();
return temp;
}
首先,如果Date temp = *this
,那么我不明白为什么这两个函数的返回类型有什么不同?一个返回*this
,另一个返回temp
,分配给*this
?
其次,为什么第二个函数的参数没有变量名?
答案 0 :(得分:6)
第一个返回this
指向的对象作为参考。也就是说,返回的对象是正在调用operator++
的对象。但是,当您执行Date temp = *this
时,temp
是根据*this
的值构建的副本。然后将其复制出函数。你从第二个函数得到的是一个全新的对象。为什么函数有这种差异在第二个问题的答案中解释。
有两种类型的增量运算符 - 一种是后增量(i++
),另一种是预增量(++i
)。为了能够单独重载它们(尽管它们具有相同的名称operator++
),C ++标准指定后增量运算符采用类型为int
的参数具有未指定的值。这很简单,您可以为操作员的每次使用重载该功能。由于您不太可能想要使用未指定的值,因此您可以将其保留为未命名。
现在,预增量运算符的预期行为是它递增对象并计算为该对象。这就是它在这种情况下返回引用的原因。后增量的预期行为是它保留原始值的副本,递增对象然后返回原始值。因此,它返回temp
副本。
答案 1 :(得分:1)
这是一个很好的问题 - 它突出了C ++设计师采用的一种相当愚蠢的设计选择:
int
参数的重载是后增量。int
参数的原因有一个 - 区分两个重载;它没有任何意义,这就是为什么它的价值永远不会被使用的原因。答案 2 :(得分:1)
第一个运算符是预递增:它递增值,并返回结果。第二个是后增量:它递增值,并返回先前的值。在该代码中,temp
保留先前的值,helpIncrement()
递增值,并返回先前的值(temp
)。参数没有名称的原因是它没有被使用。这有点像黑客;编译器知道++my_value
应该被翻译成my_value.operator++()
,并且my_value++
应该被翻译成my_value.operator++(1)
。也就是说,缺少或存在一个整数参数决定了要调用的过载。
答案 3 :(得分:1)
第一个函数在递增后返回对此的引用。第二个在递增之前返回此副本。
第二个函数中未使用的参数区分++运算符的前缀(无参数)和后缀(单个int
参数)版本。
这是一个基本主题,请阅读有关重载operator++
的内容。你可以从这里开始:Operator overloading
答案 4 :(得分:1)
首先如果Date temp = * this,那么我不明白为什么这两个函数的返回类型有什么不同?
让我们将这与好++
的{{1}}情况进行比较。考虑
int
在此之后,int i = 1;
int j = i++;
保留旧值j
,但i
本身会增加。因此,必须在增量之前复制i
,就像i
上的++
被定义为
int
OTOH,之后
class int { // pseudocode
public:
int operator++(int)
{
int temp = *this;
*this += 1;
return temp;
}
};
int i = 1;
int j = ++i;
和i
具有相同的值,因此j
必须已实现为
++
从int &operator()
{
*this += 1;
return *this;
}
到int
的更改带来了便利性:无需复制,并且在需要引用的情况下可以使用int&
。
其次,为什么第二个函数的参数没有变量名?
因为永远不应该使用它。这个参数是作为一个语法噱头,所以编译器可以区分两种类型的++i
(前后增量),但它没有任何明确定义的值。赋予其名称将在编译器中触发“未使用的标识符”选项并启用适当的警告。