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定义在此文件中 运行测试用例时,不需要去导入这个文件,会 ...
随机推荐
- pktgen-dpdk 实战
官方手册:http://pktgen-dpdk.readthedocs.io/en/latest/getting_started.html 过程 开机(重启) 把DPDK那一套流程走一遍(环境变量设置 ...
- T4模板_T4基本结构
T4文本模板由 指令块.文本块.控制块 组成. 一. 指令块(MSDN文本模板指令) 指令块以@开头,基本的指令块包括<#@ template #> .<#@ parameter# ...
- contos7忘记root密码怎么办
首先在这个界面按"e"键 然后呢就会进入到如下图所示的界面,在LANG=zh_CN.UTF8的后面加上 init=/bin/sh, 再按 [ Ctrl + X ] 进入'单用户模式 ...
- go 面试题总结
1.什么是goroutine,他与process, thread有什么区别? 2. 什么是channel,为什么它可以做到线程安全? 3. 了解读写锁吗,原理是什么样的,为什么可以做到? 4. 如何用 ...
- [转帖]Cgroups 与 Systemd
Cgroups 与 Systemd 大神的文章很牛B .. https://www.cnblogs.com/sparkdev/p/9523194.html 看不太懂 , 转帖一下 自己留着好好看呢. ...
- Caffe使用step by step:r-cnn目标检测代码
深度学习算法火起来之后,基于深度学习各种模型都如雨后春笋一般在各个领域广泛应用. 由于想把深度学习算法应用在在视频目标检测方向,得到一个较好的结果.由于视频数据的复杂性,因此使用深度学习算法在视频中的 ...
- Python2X和Python3X的区别
python2X:源码重复不规范python3X:整合源码,更清晰简单优美. python2X:默认的编码是ascii (解决办法为第一行添加 : #-*- encoding:ut ...
- Logrotate还有谁记得它??
我发现很多人的服务器上都运行着一些诸如每天切分Nginx日志之类的CRON脚本,大家似乎遗忘了Logrotate,争相发明自己的轮子,这真是让人沮丧啊!就好比明明身边躺着现成的性感美女,大家却忙着自娱 ...
- 【Java线程】SwingWorker的用法
Swing应用程序员常见的错误是误用Swing事件调度线程(Event DispatchThread,EDT).他们要么从非UI线程访问UI组件:要么不考虑事件执行顺序:要么不使用独立任务线程而在ED ...
- [OS] 内核态和用户态的区别
http://blog.csdn.net/fatsandwich/article/details/2131707# http://jakielong.iteye.com/blog/771663 当一个 ...