• 第四十课、前置操作符和后置操作符------------------狄泰软件学院


    一、i++和++i有没有区别?

    1.现代编译器产品会对代码进行优化

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

    3.优化后的二进制程序丢失了c/c++的原生语义

    4.不可能从编译后的二进制程序还原c/c++程序

     //由此可知,单行的i++和++i在汇编层的代码完全一样  
    int i = 0; 0123136E mov dword ptr [i],0 i++; 01231375 mov eax,dword ptr [i] 01231378 add eax,1 0123137B mov dword ptr [i],eax ++i; 0123137E mov eax,dword ptr [i] 01231381 add eax,1 01231384 mov dword ptr [i],eax

    二、++操作符的重载

    1、全局函数成员函数均可进行重载

    2、重载前置++操作符不需要额外的参数

    3、重载后置的++操作符需要一个int类型的占位参数编译器以此来分辨是前置还是后置操作符

    #include<iostream>
    
    using namespace std;
    
    class Test
    {
    private:
        int m_value;
    public:
        Test(int i)
        {
            m_value = i;
        }
    
        int Value()
        {
            return m_value;
        }
        //前置操作符,原生语义先自增,再将自增后的值作为返回值
      //返回值为引用,无参数 Test
    & operator ++ () { ++m_value; return *this; }
      //后置操作符,原生语义为先返回值,再增1
      //返回值为对象,有一个int类型的占位参数 Test
    operator ++ (int) { Test ret(m_value);//先保存原来的值,需要另外创建对象,所有在这里比前置操作符效率低
    m_value
    ++;//后自增
    return ret; } }; int main() { Test t0(0); Test t1(1); cout<< (t0++).Value() <<endl; //0 cout<< t0.Value() <<endl; //1 cout<< (++t1).Value() <<endl; //2 return 0; }

    三、真正的区别

    1、对于基础类型的变量

    (1)、前置++的效率与后置++的效率基本相同

    (2)、根据项目组编程规范进行选择

    2、对于类类型的变量

    (1)、前置++的效率高于后置++

    (2)、尽量使用前置++操作符提高程序效率

    四、复数类的进一步完善

    //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;
    }

    五、小结

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

    2、前置操作符后置操作符都可以重载

    3、++操作符的重载必须符合它的原生语义

    4、对于基础类型,前置++与后置++效率几乎相同

    5、对于类类型,前置++效率高于后置++

  • 相关阅读:
    大型网站架构系列:20本技术书籍推荐
    程序员进阶顺序
    乐观锁与悲观锁——解决并发问题
    Redis的事务功能详解
    驱动开发(8)处理设备I/O控制函数DeviceIoControl
    钱币兑换问题(杭电1284)(母函数)
    jqm文件上传,上传图片,jqm的表单操作,jqm的ajax的使用,jqm文件操作大全,文件操作demo
    问:简述一下内部类的实质是什么?
    Android 删除新版安卓fragment_main.xml
    保温饭盒毕业设计程序
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6364010.html
Copyright © 2020-2023  润新知