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. 手动升级 Confluence - 开始升级之前

    在本指南中,我们将会帮助你使用 zip / tar.gz 文件将你的 Confluence 安装实例在 Windows 或者 Linux 版本中升级到最新的版本. 升级到任何最新的版本都是免费的,如果 ...

  2. 八、定制new和delete

    条款49:了解new-handler的行为 new异常会发生什么事? 在旧式的编译器中,operator new分配内存失败的时候,会返回一个null指针.而现在则是会抛出一个异常. 而在抛出这个异常 ...

  3. Java indexOf() 方法

    indexOf() 方法有以下四种形式: public int indexOf(int ch): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1. public ...

  4. C_clock()测试代码(循环)运行时间

    clock()  传送门(百度百科) clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t.在MSDN中,查得对clock函数定义如下:   clock_t clock(voi ...

  5. sqli-libs(2)

    Lesson2:数字型注入我们先来测试一下 http://127.0.0.1/sql1/Less-2/?id=1%20and%201=1 发现未报错 这里知道我们的数字型注入是不需要 进行单引号闭合的 ...

  6. python3笔记二:进制转换与原码反码补码

    一:学习内容 进制:二进制.八进制.十进制.十六进制 进制转换 原码.反码.补码 二:进制 二进制 1.二进制:只有0和1,逢2进1 2.举例:0+0=0.0+1=1.1+1=10 3.过程剖析:二进 ...

  7. 选题 Scrum立会报告+燃尽图 07

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8678 一.小组情况组长:贺敬文组员:彭思雨 王志文 位军营 杨萍队名:胜 ...

  8. mybatis 中的 update 返回值

    摘自:https://www.jianshu.com/p/80270b93082a 如果定义一个如下的update函数,那么这个函数的返回值到底是啥意思呢?是受影响的行数吗? 验证之前我们先看看数据库 ...

  9. 通过实例聊聊Java中的多态

    Java中的多态允许父类指针指向子类实例.如:Father obj=new Child();  那么不禁要发问?? 使用这个父类型的指针访问类的属性或方法时,如果父类和子类都有这个名称的属性或方法,哪 ...

  10. 代码实现:编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n

    import java.util.Scanner; //编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n public ...