当重载postfix运算符时,我可以做一些简单的事情,比如
Class Foo
{
private:
int someBS;
public:
//declaration of pre &postfix++
Foo operator++();
//rest of class not shown
};
前缀不需要接受任何参数,因此当我定义它时,类似
Foo Foo::operator()
{
someBS ++;
return *this;
}
这对我来说非常有意义。
当我去定义postfix重载时,我必须包含一个虚拟的int参数
Foo Foo::operator++(int)
{
Foo temp = *this;
someBS ++;
return temp;
}
我的问题是为什么?我不会在方法中使用它。前缀运算符不需要一个。返回temp
值的后缀不依赖于伪参数。我知道,如果我希望重载一个后缀运算符以及它是如何完成的,我只想知道背后的原因。
答案 0 :(得分:5)
虚拟参数只是用于区分后缀和前缀运算符。在这两种情况下,名称++
或--
都是相同的,因此必须有某种方式来指定您定义的名称。添加一个虚拟参数可能并不优雅,但任何替代方案都可能需要发明新的语法(可能是postfix
关键字,这会破坏使用postfix
作为标识符的代码。
答案 1 :(得分:1)
引用cppreference:
int参数是一个虚拟参数,用于区分运算符的前缀和后缀版本。
引用说明了一切,因为你还能区分前缀和后缀吗?
我们只是说你不需要int
参数,那么前缀(Foo operator++()
)和后缀(Foo operator++()
)将完全相同!编译器如何知道你的意思?这就是为什么存在这个虚拟int
参数。
答案 2 :(得分:1)
在此引用C++reference:
内置运算符的前缀版本返回引用和后缀版本返回值,典型的用户定义重载遵循该模式,以便用户定义的运算符可以与内置函数相同的方式使用。
逻辑地解释:
int a = 3;
int b = 0;
int c = a + ++b;
int d = a++ + b;
在第三行中,++b
为您提供更新值的引用;在第四行中,这是不可能的:a
必须增加,因此会创建一个值副本,并添加到b
。这决定了运营商的不同语义。
实际上,只是为了避免使用另一个运营商名称:
int参数是一个虚拟参数,用于区分运算符的前缀和后缀版本。当调用用户定义的后缀运算符时,该参数中传递的值始终为零,尽管可以通过使用函数调用表示法调用运算符来更改该值(例如,a.operator ++(2)或operator ++(a,2)) 。