zoukankan      html  css  js  c++  java
  • 第40课 前置操作符和后置操作符

    值得思考的问题:

    示例:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     int i = 0;
     9 
    10     i++;
    11 
    12     ++i;
    13 
    14     return 0;
    15 }

    反汇编如下:

    我们看到i++和++i对应的汇编是完全一样的。仅仅是寄存器不一样。

    因为我们并没有使用这两行语句的返回值,而是单纯的两行i++和++i,所以编译器优化后,将返回值抛弃,因此它们的底层汇编是一样的。

    linux下g++编译器的反汇编如下:

     可以得到结论,独立的两行i++和++i是没有差别的。

    意想不到的事实:

    思考:

     ++操作符重载:

    示例程序:

    将++t的返回值来初始化tt,打印tt的值为1,这是正确的。

    添加后置++:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Test
     7 {
     8     int mValue;
     9 public:
    10     Test(int i)
    11     {
    12         mValue = i;
    13     }
    14     
    15     int value()
    16     {
    17         return mValue;
    18     }
    19     
    20     Test& operator ++ ()
    21     {
    22         ++mValue;
    23         
    24         return *this;
    25     }
    26     
    27     Test operator ++ (int)
    28     {
    29         Test ret(mValue);
    30         
    31         mValue++;
    32         
    33         return ret;
    34     }
    35 };
    36 
    37 int main()
    38 {
    39     Test t(0);
    40     
    41     t++;
    42     
    43     ++t;
    44     
    45     return 0;
    46 }

    前置++过后应该返回对象本身(引用),正如第20行所示,这也是前置++的原生语义:先将当前的操作数加1,然后返回当前的操作数。

     后置++操作符的原生语义是先将自身的值(非引用)返回,然后加1。第27行实现的正是这样的语义,通过一个临时对象来返回自身原来的值。

    后置++先将当前对象的值保存下来,只能保存到一个临时对象,因此返回时也只能返回值不能返回引用。

    前置++和后置++参数有差异,返回值也有差异。

     这里重载的前置++和后置++,在我们单独调用t++和++t时是有区别的,因为它们本质上是调用的函数,这一点不同于我们上面反汇编的++i和i++。

    后置的++会调用到构造函数和析构函数。

    因此,在回答i++和++i有没有区别时,我们要注意了,要看i是基本类型,还是我们的自定义类型。

    真正的区别:

    复数类的进一步完善:

     1 #ifndef _COMPLEX_H_
     2 #define _COMPLEX_H_
     3 
     4 class Complex
     5 {
     6     double a;
     7     double b;
     8 public:
     9     Complex(double a = 0, double b = 0);
    10     double getA();
    11     double getB();
    12     double getModulus();
    13     
    14     Complex operator + (const Complex& c);
    15     Complex operator - (const Complex& c);
    16     Complex operator * (const Complex& c);
    17     Complex operator / (const Complex& c);
    18     
    19     bool operator == (const Complex& c);
    20     bool operator != (const Complex& c);
    21     
    22     Complex& operator = (const Complex& c);
    23     
    24     Complex& operator ++ ();
    25     Complex operator ++ (int);
    26 };
    27 
    28 #endif
     1 #include "Complex.h"
     2 #include "math.h"
     3 
     4 Complex::Complex(double a, double b)
     5 {
     6     this->a = a;
     7     this->b = b;
     8 }
     9 
    10 double Complex::getA()
    11 {
    12     return a;
    13 }
    14 
    15 double Complex::getB()
    16 {
    17     return b;
    18 }
    19 
    20 double Complex::getModulus()
    21 {
    22     return sqrt(a * a + b * b);
    23 }
    24 
    25 Complex Complex::operator + (const Complex& c)
    26 {
    27     double na = a + c.a;
    28     double nb = b + c.b;
    29     Complex ret(na, nb);
    30     
    31     return ret;
    32 }
    33 
    34 Complex Complex::operator - (const Complex& c)
    35 {
    36     double na = a - c.a;
    37     double nb = b - c.b;
    38     Complex ret(na, nb);
    39     
    40     return ret;
    41 }
    42 
    43 Complex Complex::operator * (const Complex& c)
    44 {
    45     double na = a * c.a - b * c.b;
    46     double nb = a * c.b + b * c.a;
    47     Complex ret(na, nb);
    48     
    49     return ret;
    50 }
    51 
    52 Complex Complex::operator / (const Complex& c)
    53 {
    54     double cm = c.a * c.a + c.b * c.b;
    55     double na = (a * c.a + b * c.b) / cm;
    56     double nb = (b * c.a - a * c.b) / cm;
    57     Complex ret(na, nb);
    58     
    59     return ret;
    60 }
    61     
    62 bool Complex::operator == (const Complex& c)
    63 {
    64     return (a == c.a) && (b == c.b);
    65 }
    66 
    67 bool Complex::operator != (const Complex& c)
    68 {
    69     return !(*this == c);
    70 }
    71     
    72 Complex& Complex::operator = (const Complex& c)
    73 {
    74     if( this != &c )
    75     {
    76         a = c.a;
    77         b = c.b;
    78     }
    79     
    80     return *this;
    81 }
    82 
    83 Complex& Complex::operator ++ ()
    84 {
    85     a = a + 1;
    86     b = b + 1;
    87     
    88     return *this;
    89 }
    90     
    91 Complex Complex::operator ++ (int)
    92 {
    93     Complex ret(a, b);
    94     
    95     a = a + 1;
    96     b = b + 1;
    97     
    98     return ret;
    99 }

    小结:

  • 相关阅读:
    【代码笔记】iOS-书架页面
    iOS-@inerface的11条规范写法
    (转)iOS-蓝牙学习资源博文收集
    iOS App启动图不显示的解决办法.
    理解点击屏幕的事件响应--->对- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event方法的理解
    理解点击屏幕的事件响应--->对UIView的hitTest: withEvent: 方法的理解
    iOS GCD中级篇
    iOS开发UI篇—自定义layer
    iOS开发UI篇—CALayer
    iOS-绘制图层-CALayer的属性
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9573942.html
Copyright © 2011-2022 走看看