问题描述
我们知道要区分增前运算符和后增运算符,我们在后增运算符函数中使用了哑元。但是,正如我们在函数重载中所知道的那样,编译器如何内部区分这两个函数,编译器通过传递的参数数量(和参数被函数接收)来区分多个(同名)函数,但是在此我们不传递任何参数在调用时,但在函数定义的参数中我们声明为'int'。
class Integer
{
int x;
public:
void setData(int a)
{ x = a; }
void showData()
{ cout<<"x="<<x; }
Integer operator++() // Pre increment
{
Integer i;
i.x = ++x;
return i;
}
Integer operator++(int) // Post increment
{
Integer i;
i.x = x++;
return i;
}
};
void main()
{
Integer i1,i2;
i1.setData(3);
i1.showData();
i2 = ++i1; // Calls Pre-increment operator function
i1.showData();
i2.showData();
i2 = i1++; // Calls Post-increment operator function
i1.showData();
i2.showData();
}
另一个问题是,为什么i2 = i1++
调用后递增功能,为什么不提前递增。由于我们没有传递任何值,因此编译器仅调用后缀函数。是否预定义了“虚拟参数函数”仅用于后缀函数调用?
另外,是否可以将其他“浮点数”,“双精度”或其他数据类型作为伪参数而不是仅传递给“ int”?
仅将一个参数用作伪参数或多个参数?
解决方法
不确定我是否理解这个问题。编译器可以区分它们,因为它们是两个不同的运算符。 x++
与++x
不同。
也许可以认为自定义运算符只是用于调用可以重载的特殊方法的语法糖。例如,如果您有:
#include <iostream>
struct foo {
void operator++(int) {
std::cout << "post";
}
void operator++(){
std::cout << "pre";
}
};
然后,您可以通过x++
或++x
或冗长的方法调用方法:
int main()
{
foo f;
f.operator++(0);
f.operator++();
}
这与编译器决定在此处调用哪种方法没有什么不同:
void bar(int);
void bar();
bar();
bar(0);
,
对于初学者来说,预递增运算符应像这样声明和定义
Integer & operator++() // Pre increment
{
++x;
return *this;
}
在这些声明中
i2 = ++i1;
i2 = i1++;
明显可见调用了哪个运算符,即一元增量运算符
i2 = ++i1;
或后缀增量运算符
i2 = i1++;
因此,编译器在解析这些语句并选择适当的函数时没有问题。
关于最后一个问题,例如根据C ++ 14标准(递增和递减13.5.7)
1用户定义的名为operator ++的函数实现前缀 和postfix ++运算符。如果此功能是非静态成员 没有参数的函数,或者只有一个的非成员函数 参数,它为的对象定义前缀增量运算符++ 这种类型。 如果该函数是具有一个成员的非静态成员函数 参数(应为int类型)或具有以下参数的非成员函数 两个参数(其中第二个应为int类型) 为该类型的对象定义后缀增量运算符++。 由于使用++而调用后缀增量时 运算符,则int参数的值为零。1
要将一元增量运算符与后缀增量运算符显式调用区分开,您需要为后缀增量运算符指定一个等于0的参数。
例如
i1,operator ++(); // the unary increment operator
i1.operator ++( 0 ) ; // the postfix increment operator