1,C 语言中讨论了原生含义,C++ 中有必要考虑前置、后置操作符能够重载,有何问题;

2,值得思考的问题:

1,下面的代码有没有区别?为什么?

1,i++  // i 的值作为返回值,i 自增 1;

2,++i  // i 自增 1,i 的值作为返回值;

3,没有使用返回值,由于编译器(不同的编译器都是一样的)的优化,在工程上面,这两行代码没有区别;

2,真的有区别吗?编程实验:

1,main.cpp 文件:

 #include <iostream>
#include <string> using namespace std; int main()
{
int i = ; i++; ++i; return ;
}

  2,底层对应代码:

  1,工程上除了使用的寄存器有差别之外,本质没有什么差别;

  2,这是由于编译器的优化,这里是单独存在的、并没有使用它们的返回值,这个时候编译器的优化就是将返回值抛弃,得到的汇编代码就是上述内容;

3,现代编译器中的自增特性:

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

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

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

4,不可能从编译后的二进制程序还原 C/C++ 程序;

4,思考:

1,++ 操作符可以重载吗?如何区分前置 ++ 和后置 ++ ?

1,可以,-- 操作符也可以;

5,++ 操作符重载:

1,++ 操作符可以被重载:

1,全局函数和成员函数局可以进行重载;

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

3,重载后置 ++ 操作符需要一个 int 类型的占位参数;

2,++ 操作符的重载编程实验:

1,main.cpp 文件:

 #include <iostream>
#include <string> using namespace std; class Test
{
int mValue;
public:
Test(int i)
{
mValue = i;
} int value()
{
return mValue;
} Test& operator ++ () // ++ 后返回自身;
{
++mValue; // 先将当前操作数加 1; return *this; // 加 1 后返回当前的操作数;
} /* 若这个操作符不实现,则编译器显示:error: no 'operator++(int) declared for poatfix '++', try prefix operator instead */
/* C 语言中定义,如果是后置 ++,它先将当前操作数值保存在临时对象中;于是这里借助局部对象 ret 保存下来,之后返回 */
Test operator ++ (int) // 占位参数为 int 类型;
{
Test ret(mValue);// ++ 之前的值先返回,当然这里先存储着返回值,之后再 ++; mValue++; // 然后 ++ return ret;
}
}; int main()
{
Test t(); t++; ++t; return ;
}

  2,上述 main() 中的两行加加代码,因为调用函数不一样,所以有差异,并 且前置 ++ 效率更高,因为它的实现没有生成额外的对象,意味着不需要过  多的栈内存,不需要调用构造、析构函数;

6,真正的区别(本博文2 中的思考):

1,对于基础类型的变量:

1,前置 ++ 的效率与后置 ++ 的效率基本相同;

1,编译器会优化;

2,根据项目组编码规范进行选择;

2,对于类类型的对象:

1,前置 ++ 的效率高于后置 ++;

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

7,复数类的进一步完善 class Complex 编程实验:

1,Complex.h 文件:

 #ifndef _COMPLEX_H_
#define _COMPLEX_H_ class Complex
{
double a;
double b;
public:
Complex(double a = , double b = );
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);
};

 2,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;
Complex ret(na, nb); return ret;
} Complex Complex::operator - (const Complex& c)
{
double na = a - c.a;
double nb = b - c.b;
Complex ret(na, nb); return ret;
} Complex Complex::operator * (const Complex& c)
{
double na = a * c.a - b * c.b;
double nb = a * c.b + b * c.a;
Complex ret(na, nb); return ret;
} 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;
Complex ret(na, nb); return ret;
} bool Complex::operator == (const Complex& c)
{
return (a == c.a) && (b == c.b);
} bool Complex::operator != (const Complex& c)
{
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 + ;
b = b + ; return *this;
} Complex Complex::operator ++ (int)
{
Complex ret(a, b); a = a + ;
b = b + ; return ret;
} #endif

8,小结:

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

2,前置 ++ 操作符和后置 ++ 操作符都可以被重载;

3,++ 操作符的重载必须符合其原生语义;

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

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

1,对于类类型,工程中尽量使用前置 ++;

C++中前置操作符和后置操作符的重载的更多相关文章

  1. C++语法小记---前置操作符和后置操作符

    前置操作符和后置操作符 单独的"++i"和"i++"是否有区别 对于基本类型: 二者没有区别,因为编译器会对代码进行优化,二者的汇编代码完全相同 对于类类型: ...

  2. SQL中前置0和后置0的处理问题

    在sql语句中经常遇到处理前置和后置数据的问题 1.首先使用convert转化函数对预处理的数据进行转化,CONVERT()函数可以将制定的数据类型转换为另一种数据类型 MySQL 的CAST()和C ...

  3. eas之dep的前置脚本和后置脚本

    dep的前置脚本和后置脚本,什么时候写,是这样解释的:    前置脚本是在方法前执行,后置脚本是在方法后执行    1.比如保存扩展,如果你要在保存前校验某个字段的值,你要在前置脚本中写,如果要保存后 ...

  4. Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)

    原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问 ...

  5. thinkPHP 空模块和空操作、前置操作和后置操作 详细介绍(十四)

    原文:thinkPHP 空模块和空操作.前置操作和后置操作 详细介绍(十四) 本章节:介绍 TP 空模块和空操作.前置操作和后置操作 详细介绍 一.空模块和空操作 1.空操作 function _em ...

  6. thinkPHP 空模块和空操作、前置操作和后置操作 具体介绍(十四)

    本章节:介绍 TP 空模块和空操作.前置操作和后置操作 具体介绍 一.空模块和空操作 1.空操作 function _empty($name){ $this->show("$name ...

  7. Pytest里面的测试用例怎么进行前置准备和后置清理操作?

    Pytest处理前置后置有两种方式可以处理. 第一种是通过setup和teardown这样的方法去处理: 第二种是通过fixture来实现的.首先先定义fixture,然后在调用.定义fixture, ...

  8. [原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. Spring aop——前置增强和后置增强 使用注解Aspect和非侵入式配置

    AspectJ是一个面向切面的框架,它扩展了java语言,定义了AOP语法,能够在编译期提供代码的织入,所以它有一个专门的编译器用来生成遵守字节码字节编码规范的Class文件 确保使用jdk为5.0以 ...

随机推荐

  1. C# 在知道对象时编译json 而不调用json类

    StringBuilder sb = new StringBuilder();            sb.Append('[');                       foreach (va ...

  2. MongoDB下载以及安装

    一.下载与安装 1.安装Mongo MongoDB下载地址:https://www.mongodb.com/download-center?jmp=tutorials#community 运行安装程序 ...

  3. R_Studio(学生成绩)绘制频率分布直方图、分布饼图、折线比较图

    对“Gary.csv”中的成绩数据进行分布分析 (1)按0-59,60-69,70-79,80-89,90-100分组绘制高级语言程序设计成绩的频率分布直方图. (2)按0-59,60-69,70-7 ...

  4. 分布式-信息方式-JMS大纲

     一.简介 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息, ...

  5. CommandLineRunner and ApplicationRunner

    1. Run spring boot as a standalone application (non-web) <?xml version="1.0" encoding=& ...

  6. java多线程的应用场景

    通俗的解释一下多线程先: 多线程用于堆积处理,就像一个大土堆,一个推土机很慢,那么10个推土机一起来处理,当然速度就快了,不过由于位置的限制,如果20个推土机,那么推土机之间会产生相互的避让,相互摩擦 ...

  7. IntelliJ IDEA 常用快捷键整理

    1. -----------自动代码--------  常用的有fori/sout/psvm+Tab即可生成循环.System.out.main方法等boilerplate样板代码 例如要输入for( ...

  8. LeetCode75----分类颜色(变相快排)

    给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示红色.白色和蓝色. ...

  9. TCP之LAST_ACK状态

    前提: A:主动关闭: B:被动关闭: A执行主动关闭,发送FIN,B收到FIN,发送ACK,进入CLOSE_WAIT,B发送FIN,进入LAST_ACK等待最后一个ACK到来: 关闭方式: (1) ...

  10. CopyOnWriteArrayList使用

    1.在遍历操作数量大大超过可变操作是(add,set等等)使用.原因是其可变操作是通过对底层数据进行一次新的复制来实现的. 2.迭代器创建后,其不会反应列表的添加.移除或更改.其迭代器是”快照“风格的 ...