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定义在此文件中 运行测试用例时,不需要去导入这个文件,会 ...
随机推荐
- javascript修改div大小遮挡页面渲染问题
页面中引入了其他js文件,浏览器窗口改变,页面没有跟随渲染问题.最后找到原因是因为这个js方法少了最后一行: "right": RightBox_w. window.onresiz ...
- 修改shell命令的history记录个数
修改history记录的命令如下所示:# vi /etc/profile 找到histsize=1000,将其改为histsize=100(这条可根据实际情况而定). 不重启系统就可让其生效,如下所示 ...
- 软工网络15团队作业8——Beta阶段敏捷冲刺(day1)
第 1 篇 Scrum 冲刺博客 1. 介绍小组新加入的成员,Ta担任的角色 --给出让ta担当此角色的理由 小组新加入的成员:3085叶金蕾 担任的角色:测试/用户体验/开发 理由:根据小组讨论以及 ...
- 有意思的Alias参数
1. 最简单的方式,运行正常. PS C:\> Get-Service -Name BITS -ComputerName localhost 2. 自己构造一个对象,试图通过管道将主机名传递下去 ...
- Qt宏Q_OBJECT展开记录
c++中的宏 #define A 3.14 展开后把A替换为B #define A(a) #a 展开后用a的字符串替换A(a) #define A(a) a##B 展开后把a和B的字符串连接起来后替换 ...
- 微信公众平台实现获取用户OpenID的方法
这篇文章主要介绍了微信公众平台实现获取用户OpenID的方法,需要开发人员经过微信授权后获取高级接口才能使用此功能,用户OpenID对于微信公众平台建设有着非常广泛的用途,需要的朋友可以参考下 本文实 ...
- [细品java]ThreadLocal源码学习
ThreadLocal是线程局部变量,其中保存了特定于该线程的值.每个线程都拥有一份独立的副本值,即每个线程修改变量值不影响其他线程该变量的副本值.这些特定于线程的值保存在Thread对象中,当线程终 ...
- Nagios学习笔记
1 Nagios功能 1.1 监控工具 1.2 可以监控主机/服务或者资源 1.3 四种状态值 OK,WARNING,CRITICAL,UNKNOWN CPU:90%(CRITICAL),80% ...
- Java词频统计
public class WordCount { public static void main(String[] args) { String[] stopWords = { "" ...
- NOI2017 退役记
OI生涯最后一篇游记写点不开心的让大家开心一下 Day -2(7.16) 上午的模拟赛奥妙重重. 下午也没怎么改题,看了一些新题,发现都不会,都看了下题解,发现大部分没看懂,好慌. 发现板子还没怎么复 ...