哑元与运算符重载:前缀++与后缀++

柔情只为你懂 2022-07-14 14:08 143阅读 0赞

哑元
首先,我们了解下什么是哑元及哑元的作用,某个参数如果在子程序或函数中没有用到,那就被称为哑元。这是程序设计语言中的一个术语,不是FORTRAN独有的,函数的形参又称“哑元”,实参又称“实元”。在C++的运算符重载中,就会用到哑元以区分i++与++i的区别:)且在C/C++中,哑元是可以没有变量名的,如:

  1. int fun(int,int a){
  2. return a/10*10;
  3. }

则在调用时,第一个参数随便给一个值就行了,因为它终会被丢弃。哑元表示虚无的元素,没有实际空间,甚至连名字都可以没有,它只有联系上实元才有意义。
声明并定义一个函数 :

  1. void f(int)
  2. {
  3. }

函数f有一个int参数,但没有给这个参数声明变量,所以在函数的实现中你永远也无法使用这个函数,这个参数只是一个占位符,一般是因为兼容性方面的原因这样做的。又或者在++操作符定义中也需要这种占位符。例如下面的例子就是哑元在运算符重载中的一个应用:
首先,思考一个问题,我们知道重载是通过参数列表的不同来识别函数,但是 编译器如何识别重载的可以前置或后置的自增及自减运算符函数呢?
答案是一样的,通过函数的参数列表的不同。后置自增运算符的参数里有个哑元,而前置自增运算符函数的参数里没有。记住,如果有哑元,则是postfix(后置),否则,就是prefix(前置)

前置:先自增后返回,因此前置自增运算符用新值返回实际自增的对象。这种对象在连续表达式中被用作左值。(引用,改变值再返回)
后置:后置自增运算符通常在自增前返回一个包含对象原始值的临时对象。c++将这样的对象视为右值,不能用于赋值运算符的左边。(先把数值(形参int)返回,再自增),例如,我们看个实际的代码例子:

  1. int i=10;
  2. cout<<i++<<endl; //i=11;后缀加;先返回后自增; 10
  3. cout<<++i<<endl; //i=12;前缀加;先自增后返回; 12
  4. #include <iostream>
  5. using namespace std;
  6. class Plus
  7. {
  8. public:
  9. Plus(int I=1);
  10. Plus &operator++();//前置++,若返回值不是引用类型,则结果也对,只是返回值不能作为左值被赋值了
  11. Plus operator++(int);//后置++
  12. void print();
  13. private:
  14. int i;
  15. };
  16. Plus::Plus(int I)
  17. {
  18. i=I;
  19. }
  20. Plus &Plus::operator ++()//前置++,返回this对象的引用,可以作为左值,被赋值。
  21. {
  22. i+=1;
  23. return *this;
  24. }
  25. Plus Plus::operator ++(int)//后置++,返回临时对象temp的值,只能作为右值,不能被赋值。
  26. {
  27. Plus temp=*this;//把当前调用此函数的对象的值赋给temp对象,即拷贝构造
  28. ++(*this);//调用的是重载的前置版本
  29. return temp;//返回的是未经修改的值
  30. }
  31. void Plus::print()
  32. {
  33. cout<<"i="<<i<<endl;
  34. }
  35. int main()
  36. {
  37. Plus a(5),b;
  38. a.print();//5
  39. ++a;//a.operator++(),若此处写成++a=b,则相当于是a=b,a被b赋值。
  40. a.print();//6
  41. b=a++;
  42. b.print();//6
  43. a.print();//7
  44. a++;//a.operator++(0)伪值0用于区分前置还是后置
  45. a.print();//8
  46. return 0;
  47. }

前置版本返回一个引用Plus &Plus::operator++(),后置版本返回一个值 Plus Plus::operator ++(int)。
后置版本是利用前置版本来实现的。节约代码,控制代码有余。
前置版本的效率高,因为后置版本需要调用前置版本,所有后置版本效率比前置要低。(++i比i++效率高)
在后置版本里,人为添加一个参数(int),主要是为了区别前置版本,这个参数不会被使用。

英文原版,即C++发明者的解释https://isocpp.org/wiki/faq/operator-overloading#increment-pre-post-overloading

发表评论

表情:
评论列表 (有 0 条评论,143人围观)

还没有评论,来说两句吧...

相关阅读