c++ 前置++与后置++的区别
用C++编程的都知道,C++提供了一个非常强大的操作符重载机制,利用操作符重载,我们可以为我们自定义的类增加更多非常有用的功能。不过,C++也有限制,就是当我们为自定义的类重载操作符时,重载操作符的含义应该跟内置类型一样,比如,你不能通过重载+号操作符来实现两个数相乘的运算,实现需要是两个数相加的运算。本篇,我重点介绍下重载前置++和后置++的区别(前置--跟后置--类似)。
我们知道,写for循环年的时候,可以用下面这两种方式:
for(int i=; i<; i++) {
//do something
} for(int j=; j<; ++j) {
//do something
}
如上两种方式,i++跟++j到底有什么区别呢?
首先,这两种方式都会使得i跟j自增1, 不同的地方在于其内部实现; i++的实现原理是现将i自增1,然后返回i的引用(我们知道重载操作符也是可以有返回值的);而++j的实现原理是:先定义一个j的副本,然后在将j自增1,最后返回之前定义个那个副本的值。
通常,c++的内置类型都要求前缀式操作符返回被增量或被减量对象的引用;而要求后缀式操作符返回被增量活被减量对象做增或减操作之前的副本(这里边就存在内存拷贝)。
实际的调用过程看起来应该是这样:
for( int i=; i<; i.operator++() ) { //调用后置++
//do something
} for( int i=; i<; i.operator++() ) { //调用前置++
//do something
}
看到这里,你可能 有个疑问,为什么调用后置++的之后,参数列表要传一个0而前置++却没有传呢?
这里就牵扯出前置++跟后置++的另一个差别。
前置++和后置++在定义的都是一样,看起来应该是下边这样:
class A {
private:
int a;
public: A& operator++() {
//...
} A operator++() {
//...
} }
这样,我们就无法区分到底哪个是哪个了,也许你会说它们的返回值不是不一样吗? 我们老早就知道,无法通过不同的返回值来重载不同的函数版本。
这种情况下,为了做区分也是为了解决这一问题,一般要求后缀式操作符接受一个额外的int型形参(不会使用它,仅做区分用),来区别两者的不同。
class A {
private:
int a;
public: A& operator++() { //前置++
//...
} A operator++(int) { //后置++
//...
} }
这样,编译器将为我们提供0作为这个后缀式版本的形参。(也可以调用这个有参数的版本做前缀式操作,不过一般不应该这么做),下边是完整定义:
class A {
private:
int a;
public: A& operator++() { //前置++
++a;
return *this;
} A operator++(int) { //后置++
A a = *this;
++*this;
returnn a;
} }
如上,操作符的后缀式比前缀式复杂一些,在实现后缀式版本时,一般先保存对象做自增/减之前的副本,然后调用自己的前缀版本来实现自增操作,最后将先前年保留的副本
返回。这里需要注意的是,后缀式版本中,返回值是尚未自增的原值,但对象本身已经做了自增操作了。
( ps : --操作符的前缀式和后缀式类型)
c++ 前置++与后置++的区别的更多相关文章
- C++前置++与后置++的区别与重载
++属于单目运算符,前置与后置的实现代码不一样,下面以整数自增为例: // 前置++,返回自增后的值,且返回的是一个左值 int& operator++(){ *this += 1; retu ...
- JavaScript运算符:递增递减运算符前置和后置的区别
从两段代码说起 var num1 = 2; var num2 = 20; var num3 = --num1 + num2; var num4 = num1 + num2; console.log(n ...
- C++之运算符重载(前置++和后置++)
今天在阅读<google c++ 编程风格>的文档的时候,5.10. 前置自增和自减:有一句话引起了我的注意: 对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.,理 ...
- C++的前置++、后置++和前置--、后置--
一.C++的前置++和后置++ 在C++中,运算符重载是你必须要掌握的重点,而前置++和后置++有什么区别呢?其实前置++和后置++是有关于 影响效率的问题,前置++比后置++的效率要高,原因是因为前 ...
- android Camera 如何判断当前使用的摄像头是前置还是后置
现在 android 平台的智能手机一般都标配有两颗摄像头.在 Camera 中都存在摄像头切换的功能. 并且有一些功能前后置摄像头上会有所不同.譬如人脸检测,人脸识别,自动对焦,闪光灯等功能, 如果 ...
- ThinkPHP - 前置操作+后置操作
前置操作和后置操作 系统会检测当前操作(不仅仅是index操作,其他操作一样可以使用)是否具有前置和后置操作,如果存在就会按照顺序执行,前置和后置操作的方法名是在要执行的方法前面加 _before ...
- PHP通过__call实现简单的AOP(主事务后的其他操作)比如前置通知,后置通知
/** * person class */ class Person { /** * person class -> function say */ public static function ...
- 20_AOP_Advice增强1(前置、后置、环绕)
[增强的类型] 1.前置增强:org.springframework.aop.BeforeAdvice. 由于Spring只支持方法级别的增强,所以MethodBeforeAdvice是目前可用的前置 ...
- pytest框架之fixture前置和后置
一.conftest.py 定义公共的fixture,多个测试类中都可以调用 pytest提供了conftest.py文件,可以将fixture定义在此文件中 运行测试用例时,不需要去导入这个文件,会 ...
随机推荐
- 简单的树(summary)
实验任务 可怜的 Bibi 丢了好几台手机以后,看谁都像是小偷,他已经在小本本上记下了他认为的各个地点的小偷数量. 现在我们将Bibi的家附近的地形抽象成一棵有根树.每个地点都是树上的 一个节点,节点 ...
- Scrum 5.0(继4.0)
一,组员任务完成情况 首页设计初步完成但是需要优化界面,只能简单的输出信息和在首页进行登录.界面极其简单. 鸡汤版面设计有困难,问题在于用何种形式来管理用户的数据上传,但是经过小组间的讨论确定设计方向 ...
- 使用IPMI操作Dell服务器
机房里有5台实验用的Dell R710服务器,为了低碳环保,我决定只在工作日白天开启它们,其余时间全部关闭.我选择在linux下用ipmitool结合计划任务来实现,这里只记录ipmitool工具的用 ...
- ognl用法 取变量时候 需要在变量前面加上# 取字符串需要用单引号包裹字符串
- BZOJ5321 JXOI2017加法(二分答案+贪心+堆+树状数组)
二分答案后得到每个位置需要被加的次数.考虑贪心.从左到右考虑每个位置,将以该位置为左端点的区间按右端点从大到小加进堆.看该位置还需要被加多少次,如果不需要加了就不管,否则取堆顶区间将其选择,BIT实现 ...
- static变量 方法 类 和final
static变量:声明为static的变量实质上就是全局变量.当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量.静态变量与静态方法类似.所有此类实例共 ...
- How Many Points? LightOJ - 1077(线段经过整点个数与gcd 证明)
题意: 已知两点 (x1,y1) 和 (x2, y2)求两点间线段上的整点的个数 解析: 就是求gcd(abs(x2- x1),abs(y2 - y1)) 证明: 我们分水平方向和竖直方向两个方向看 ...
- [BZOJ4446]SCoi2015 小凸玩密室 树形DP(烧脑高能预警)
4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec Memory Limit: 128 MB Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点 ...
- 快速配置java环境变量
右键单击计算机--->属性 点击 “高级系统设置”--->"环境变量",出现环境变量设置窗口 系统变量--->新建 JAVA_HOME变量,变量值填写jdk安装路 ...
- 【转】iBatis.Net的SqlMap.config文件
转自:http://www.xuebuyuan.com/579671.html iBatis.Net基本的运行环境配置主要由两个文件组成,分别是SqlMap.config和Provider.con ...