• 第40课 前置操作符和后置操作符


    1. ++ii++真的有区别吗?

    (1)现代编译器会对代码进行优化

    • 对于基础类型前置++和后置++汇编代码几乎是一样的,最终效率完全一样

    (2)优化使得最终的二进制程序更加高效

    (3)优化后的二进制程序丢失了C/C++的原生语义

    (4)不可能从编译后二进制程序还原C/C++程序

    【编程实验】真的有区别吗?   40-1.cpp

      int i = 0;
    
    013612FB  mov         dword ptr [i],0 
    
     
    
        i++;
    
    01361302  mov         eax,dword ptr [i] 
    
    01361305  add         eax,1 
    
    01361308  mov         dword ptr [i],eax 
    
     
    
        ++i;
    
    0136130B  mov         ecx,dword ptr [i] 
    
    0136130E  add         ecx,1 
    
    01361311  mov         dword ptr [i],ecx 
    
     

    2. ++操作符的重载

    (1)可利用全局函数成员函数进行重载

    (2)重载前置++操作符(如++i不需要额外的参数

    (3)重载后置++操作符(如i++需要一个int类型的占位参数(即编译器通过有无这个占位符来区别是重载前置还是后置++操作符)

    【编程实验】++操作符的重载   40-2.cpp

    #include <iostream>
    
    using namespace std;
    
     
    
    class Test
    {
    
        int mValue;
    
    public:
    
        Test(int i){mValue = i;}
    
       
    
        int value(){return mValue;}
    
       
    
        //前置++(如++i),原生语义先自增后取值
    
        //返回值为引用,无参!
    
        Test& operator ++() 
        {
    
            ++mValue;    //先自增
    
            return *this;//后取值
    
        }
    
       
    
        //后置++(如i++),原生语义先取值后自然
    
        //返回值为对象,int型参数作占位符,以区别前置和后置++
    
        Test operator ++(int)
        {
    
            Test ret(mValue); //先取值
    
           
    
            mValue++;         //后自增
    
           
    
            return ret;       //注意,这里返回自增之前的对象状态
    
        }
    
    };
    
     
    
    int main()
    {
    
        Test t(0);
    
       
    
        printf("t.value() = %d
    ",(t++).value()); //0;
    
        //printf("t.value() = %d
    ",(++t).value()); //1;
    
       
    
        return 0;
    
    }

    运行结果:

      

    3. 真正的区别

    (1)对于基础类型的变量

      ①前置++的效率与后置++效率基本相同

      ②根据项目组编码规范进行选择

    (2)对于类类型的对象

      ①前置++的效率高于后置++

      ②尽量使用前置++操作符提高程序效率

    【编程实验】复数类的进一步完善   Complex

    //Complex.h

    #ifndef _COMPLEX_H_
    
    #define _COMPLEX_H_
    
     
    
    class Complex
    {
    
    private:
    
        double a;
    
        double b;
    
     
    
    public:
    
        Complex(double a = 0, double b = 0);
    
        double getA();
    
        double getB();
    
        double getModulus();
    
     
    
        Complex operator + (const Complex& c);
    
        Complex operator - (const Complex& c);
    
        Complex operator * (const Complex& c);
    
        Complex operator / (const Complex& c);
    
     
    
        bool operator == (const Complex& c);
    
        bool operator != (const Complex& c);
    
     
    
        Complex& operator = (const Complex& c);
    
       
    
        Complex& operator ++();   //前置++
    
        Complex operator ++(int); //后置++
    
    };
    
     
    
    #endif

    //Complex.cpp

    #include "Complex.h"
    
    #include <math.h>
    
     
    
    Complex::Complex(double a, double b)
    
    {
    
        this->a = a;
    
        this->b = b;
    
    }
    
     
    
    double Complex::getA()
    
    {
    
        return a;
    
    }
    
     
    
    double Complex::getB()
    
    {
    
        return b;
    
    }
    
     
    
    double Complex::getModulus()
    
    {
    
        return sqrt(a * a + b * b);
    
    }
    
       
    
    Complex Complex::operator + (const Complex& c)
    
    {
    
        double na = a + c.a;
    
        double nb = b + c.b;
    
     
    
        return Complex(na, nb);
    
    }
    
     
    
    Complex Complex::operator - (const Complex& c)
    
    {
    
        double na = a - c.a;
    
        double nb = b - c.b;
    
     
    
        return Complex(na, nb);
    
    }
    
     
    
    Complex Complex::operator * (const Complex& c)
    
    {
    
        double na = a * c.a - b * c.b;
    
        double nb = a * c.b - b * c.a;
    
     
    
        return Complex(na, nb);
    
    }
    
     
    
    Complex Complex::operator / (const Complex& c)
    
    {
    
        double cm = c.a * c.a + c.b * c.b;
    
        double na = (a * c.a + b * c.b) / cm;
    
        double nb = (b * c.a - a * c.b) / cm;
    
     
    
        return  Complex(na, nb);
    
    }
    
       
    
    bool Complex::operator == (const Complex& c)
    
    {
    
        return (a == c.a) && (b = c.b);
    
    }
    
     
    
    bool Complex::operator != (const Complex& c)
    
    {
    
        //整个复数对象就两个成员,如果这个2个对象的
    
        //内存完全相等时,则两个复数相等
    
        return !(*this == c);
    
    }
    
     
    
       
    
    Complex& Complex::operator = (const Complex& c)
    
    {
    
          if(this != &c)
    
        {
    
            a = c.a;
    
            b = c.b;
    
        }
    
        return *this;
    
    }
    
     
    
    Complex& Complex::operator ++()  //前置++
    
    {
    
        a = a + 1;
    
        b = b + 1;
    
       
    
        return *this;
    
    }
    
     
    
    Complex Complex::operator ++(int) //后置++
    
    {
    
        Complex ret(a, b);
    
       
    
        a = a + 1;
    
        b = b + 1;
    
       
    
        return ret;
    
    }

    //main.cpp

    #include <stdio.h>
    
    #include "Complex.h"
    
     
    
    int main()
    
    {
    
        Complex c1(0, 0);
    
        Complex t1 = c1++;
    
        Complex t2= ++c1;
    
     
    
        printf("t1.a = %f, t1.b = %f
    ",t1.getA(), t1.getB());//0, 0
    
        printf("t2.a = %f, t2.b = %f
    ",t2.getA(), t2.getB());//2, 2
    
     
    
        return 0;
    
    }

    运行结果:

      

    4. 小结

    (1)编译优化使得最终的可执行程序更加高效

    (2)前置++操作符后置++操作符都可以被重载

    (3)++操作符的重载必须符合其原生语义(即前置就先取值再自增,后置应先自增再取值)

    (4)对于基础类型前置++后置++效率几乎相同

    (5)对于类类型前置++的效率高于后置++

  • 相关阅读:
    BestCoder Round #61 (div.2)
    CCPC L(水)
    CCPC A(模拟)
    暗网是什么?如何进入暗网?
    社会工程学:关于一些信息收集的网站
    Flask开发系列之Web表单
    Flask开发系列之模板
    [转]Python 资源大全中文版
    python字符串/列表/字典互相转换
    Flask开发系列之Flask+redis实现IP代理池
  • 原文地址:https://www.cnblogs.com/hoiday/p/10166474.html
Copyright © 2020-2023  润新知