码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-05-06 20:18:39      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:

1. ++i和i++真的有区别吗?

(1)现代编译器会对代码进行优化。对于基础类型,前置++和后置++的汇编代码几乎是一样的,最终效率完全一样

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

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

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

    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类型的占位参数。(即编译器通过有无这个占位符来区别是重载前置还是后置++操作符)

【编程实验】++操作符的重载

#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\n",(t++).value()); //0;
    //printf("t.value() = %d\n",(++t).value()); //1;
    
    return 0;
}

3. 真正的区别

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

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

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

(2)对于类类型的对象

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

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

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

//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\n",t1.getA(), t1.getB());//0, 0
    printf("t2.a = %f, t2.b = %f\n",t2.getA(), t2.getB());//2, 2

    return 0;
}

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

4. 小结

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

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

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

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

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

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

标签:

原文地址:http://www.cnblogs.com/5iedu/p/5466839.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!