浅谈C++中如何重载前置++/--与后置++/--

- 日理万妓 2024-02-17 11:15 111阅读 0赞

前置++/–与后置++/–

C++中的++和–操作符存在前置式与后置式,最基本的,作为一名程序员,你应当了解它们实现的不同:

  1. i++;
  2. ++i;

以上两行代码如果单独使用,在功能上是一致的,它们都实现了让变量i加1的操作,但是实现的机制有所不同:

  • i++是先用后加,即你在t时刻得到的变量i的值实际上还是原来的值,但它实际的值已经被加1;
  • ++i是先加后用,即你用的值和变量i当前时刻的值是一样的;

    int a = 1;

    1. int b = 1;
    2. cout << "a: " << a << " 前++: " << ++a << " a:" << a << std::endl;
    3. cout << "b: " << b << " 后++: " << b++ << " b:" << b << std::endl;

运行结果:

  1. a: 1 前++: 2 a:2
  2. b: 1 后++: 1 b:2

发现没有?后置式其实是将变量的值找了个临时变量先存了起来,然后再将该变量加1,而前置式则直接将变量加1。

从这个机制上,可以下个结论,后置式在性能上要逊与前置式。这其实也是在建议你,在写for循环时尽量使用前置式++i,而不是后置式i++。

前置++/–与后置++/— 的重载

C++允许这两个操作符拥有重载能力。但是这时候你可能发现在语法上似乎出现了问题:重载函数是以其参数类型或个数来区分彼此的,然而这是个单目运算符,无论是前置式还是后置式,都没有参数。于是,为了填平这个语言上的漏洞,只好让后置式有一个int自变量,在其被调用的时候,编译器默默为该int指定一个0值。

假设我们有一个复数类complex,现在为其重载++运算符:

  1. class complex
  2. {
  3. public:
  4. complex& operator++()
  5. {
  6. a = a+1;
  7. b = b+1;
  8. return *this;
  9. };
  10. const complex operator++(int)
  11. {
  12. complex temp = *this;
  13. ++temp;
  14. return temp;
  15. };
  16. int a = 0;
  17. int b = 0;
  18. };

其实,前置++与后置++的功能”先加后用“与”先用后加“已经为这两种操作符的实现指明了路线:既然是先加后用,那加完之后的和最后使用的应当是同一样东西,所以应当返回引用。同理,”先用后加“说明应当先把原来的值保存起来,再将其加1,但是最后还是应当返回其原来的值,因为是”先用后加“嘛。另外,你还应当注意,这里保存完原来的值之后,直接调用了前置++去实现加1,这种操作很好的实现了复用,应当被提倡。

但是,你可能会奇怪:为什么后置++必须返回一个const值?而不是像前置++一样返回引用就好了?

首先,返回值是因为这是个局部变量,一旦出了作用域,temp的生命周期就完结了,也就不存在引用了;其次,const 其实是在像”偶像”致敬。偶像?谁是偶像?int。

是的,当你不清楚你的实现应当跟谁保持一致的时候,去看看标准库里的数据类型,int类型支持++ ++ i,但是不支持i++ ++。所以,为了跟标准保持一致,建议像偶像看起。因此,返回const值也就说得通了。

最后,附上源码:

  1. #include <iostream>
  2. class complex
  3. {
  4. public:
  5. complex& operator++()
  6. {
  7. a++;
  8. b++;
  9. return *this;
  10. };
  11. const complex operator++(int)
  12. {
  13. complex temp = *this;
  14. ++temp;
  15. return temp;
  16. };
  17. int a = 0;
  18. int b = 0;
  19. };
  20. std::ostream& operator<<(std::ostream& os, const complex& value)
  21. {
  22. os << value.a << " " << value.b << " ";
  23. return os;
  24. }
  25. int main()
  26. {
  27. int a = 1;
  28. int b = 1;
  29. cout << "a: " << a << " 前++: " << ++a << " a:" << a << std::endl;
  30. cout << "b: " << b << " 后++: " << b++ << " b:" << b << std::endl;
  31. complex c;
  32. cout << "c: " << c << " 前++++: " << ++ ++c << " 后++ " << c++ << std::endl;
  33. return 0;
  34. }

发表评论

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

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

相关阅读