C++中前置操作符和后置操作符的重载
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++中前置操作符和后置操作符的重载的更多相关文章
- C++语法小记---前置操作符和后置操作符
前置操作符和后置操作符 单独的"++i"和"i++"是否有区别 对于基本类型: 二者没有区别,因为编译器会对代码进行优化,二者的汇编代码完全相同 对于类类型: ...
- SQL中前置0和后置0的处理问题
在sql语句中经常遇到处理前置和后置数据的问题 1.首先使用convert转化函数对预处理的数据进行转化,CONVERT()函数可以将制定的数据类型转换为另一种数据类型 MySQL 的CAST()和C ...
- eas之dep的前置脚本和后置脚本
dep的前置脚本和后置脚本,什么时候写,是这样解释的: 前置脚本是在方法前执行,后置脚本是在方法后执行 1.比如保存扩展,如果你要在保存前校验某个字段的值,你要在前置脚本中写,如果要保存后 ...
- Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)
原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问 ...
- thinkPHP 空模块和空操作、前置操作和后置操作 详细介绍(十四)
原文:thinkPHP 空模块和空操作.前置操作和后置操作 详细介绍(十四) 本章节:介绍 TP 空模块和空操作.前置操作和后置操作 详细介绍 一.空模块和空操作 1.空操作 function _em ...
- thinkPHP 空模块和空操作、前置操作和后置操作 具体介绍(十四)
本章节:介绍 TP 空模块和空操作.前置操作和后置操作 具体介绍 一.空模块和空操作 1.空操作 function _empty($name){ $this->show("$name ...
- Pytest里面的测试用例怎么进行前置准备和后置清理操作?
Pytest处理前置后置有两种方式可以处理. 第一种是通过setup和teardown这样的方法去处理: 第二种是通过fixture来实现的.首先先定义fixture,然后在调用.定义fixture, ...
- [原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Spring aop——前置增强和后置增强 使用注解Aspect和非侵入式配置
AspectJ是一个面向切面的框架,它扩展了java语言,定义了AOP语法,能够在编译期提供代码的织入,所以它有一个专门的编译器用来生成遵守字节码字节编码规范的Class文件 确保使用jdk为5.0以 ...
随机推荐
- python之timeit模块
timeit模块: timeit 模块定义了接受两个参数的 Timer 类.两个参数都是字符串. 第一个参数是你要计时的语句或者函数. 传递给 Timer 的第二个参数是为第一个参数语句构建环境的导入 ...
- python学习之路(13)
列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, ...
- WordPress 主题开发:从入门到精通(必读)
本专栏介绍如何开发设计你自己的 WordPress 主题.如果你希望了解更多如何安装和应用主题的内容,请参阅应用主题文档.本文的内容不同于应用主题,因为所讨论的是编写代码去构建你自己的主题的技术内容, ...
- CentOS 7,使用yum安装Nginx
https://www.centos.bz/2018/01/centos-7%EF%BC%8C%E4%BD%BF%E7%94%A8yum%E5%AE%89%E8%A3%85nginx/ 文章目录 [隐 ...
- 云服务器搭建anaconda pytorch torchvision
(因为在普通用户上安装有些权限问题安装出错,所以我在root用户下相对容易安装,但是anaconda官网说可以直接在普通用户下安装,不过,在root下安装,其他用户也是能用的. 访问Anaconda官 ...
- ASP.NET中的物理路径与虚拟路径
物理路径:c:\PathsAndURLs\Content\Colors.html虚拟路径:(http://localhost:53274/Content/Colors.html)路径中端口号后面的那部 ...
- 后盾网lavarel视频项目---5、淘宝镜像cnpm的原理及如何使用
后盾网lavarel视频项目---5.淘宝镜像cnpm的原理及如何使用 一.总结 一句话总结: 原理:把npm上面的所有软件copy过来 使用:npm install -g cnpm --regist ...
- legend3---laravel中获取控制器名称和方法名称
legend3---laravel中获取控制器名称和方法名称 一.总结 一句话总结: \Route::current()->getActionName();会有完整的当前控制器名和方法名 pub ...
- html实现高亮检索
实现效果如下: demo.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- Oracle数据表之间的数据同步
保证两个数据表结构相同,如不相同只能同步相同字段; 只是思路,具体请根据需求修改. declare cursor csrn_mon is select * from table2; row_mon c ...