一、先看下面两段完全一样的代码块

/* test.cpp */
int main()
{
int a = 5;
++a = 7;
printf("%d\n", a);
return 0;
}
/* test.c */
int main()
{
int a = 5;
++a = 7;
printf("%d\n", a);
return 0;
}

  在test.cpp文件与test.c文件下会分别显示什么呢?运行结果显示,在test.cpp下打印出 7 , 而在test.c下编译出错,报错信息:

二、前置自增

  乍一看++a = 7; 这条语句很奇怪,本以为会在C++里编译报错,没想到居然成功输出了7。

  学过C一定对前置自增“先+1,再返回”的操作很熟悉了,++a 会对a值先+1,再返回a当前的值(也就是6),注意在C里返回的是“值”(value)而不是 “引用”(reference),因此在test.c中 ++a = 7; 由于++a返回的是6这个右值,因此也就不能作为=的左操作数。

  而在C++里由于加入了引用这个概念,因此,++a会先对a值+1,再返回a的引用(是一个左值)。因此在C++标准中对于前置自增的运算符重载操作返回的也是 Object& 而不是 Object。

三、后置自增

  相对于前置自增,后置自增的操作是“先返回当前值,再+1”,也即 a++ 执行的是 int tmp = a; ++a; return tmp; 后置自增无论在C里还是C++里返回的都是值(Value),因此在后置自增上并没有太大的区别。由于后置自增返回的是值(Value),因此对于a++ = 7;这条语句,不论是在C++还是C中都会编译报错的。

  说到这可能有人会想到,既然C++里加入的引用可以作为前置自增的返回类型,为什么后置自增的返回不用引用呢?

  (1)首先,a++ <==> { int tmp = a; ++a; return tmp;  } ,tmp是一个临时变量,无法返回其引用。

  (2)在C++ Primer中明确说明了,C++中前置自增返回的是引用,后置自增则将对象原始值的副本作为右值返回既然要作为右值返回,后置自增的运算符重载的返回类型 就应该是 const Object,这样对于任何一个以 const Object作为返回类型的后置自增运算符重载,类似于 a++ = 7这样的语句都会报错,也即 a++返回了一个右值(rvalue)

四、运算符重载示例

  关于前置++后置++的重载,详细可查<<More Efficitive C++ >> 条款6;

class A {
public:
A(int a) : m_data(a) {} A& operator++(){ //前置自增,返回 Object &
m_data += 1;
return *this;
} const A operator++(int) { //后置自增, 返回 const Object ,右值
A tmp(m_data);
++*this;
return tmp;
} A& operator=(const A& a) {
this->m_data = a.m_data;
return *this;
}
//private:
int m_data;
}; /* test.cpp */
int main()
{
A a(5);
A b(10);
++a = b; // ++a返回a本身,>> a.m_data = 10;
cout << a.m_data << endl;
cout << (b++).m_data << endl; // b++返回tmp副本作为右值,>> 10
//(b++) = a; //error, b++返回的是右值 }

五、参考

  <<More Efficitive C++ >> 条款6;

  <<C++ Primer 5th 中文版>> 4.5 递增和递减运算符

  

C和C++区别——前置自增与后置自增的更多相关文章

  1. C++之前置自增与后置自增

    关于前置自增与后置自增的区别我是参考这里:http://bbs.bccn.net/thread-454977-1-1.html 简单复述下,比如++x; 与 x++; 在C中,++x这个表达式的值为原 ...

  2. c++重在运算符前置自增和后置自增

    class student { int age; }; int main() { class student stu; (stu++)++;//error ++(stu++);//error stu+ ...

  3. C: printf参数执行顺序与前置后置自增自减的影响

    起源: 今天在了解副作用side-effect的过程中,看到了下面的网页,把我带到了由printf引起的一系列问题,纠结了一整天,勉强弄懂. 第一个代码没什么好解释的.而第二个printf(" ...

  4. HTML5 选择前置摄像头,选择后置摄像头

    最近发现我写的都是乱七八糟的,觉得应该给大家带点福利,于是写了这篇 背景:最近想做个web应用,需要用到摄像头,但是发现默认一直是前置摄像头,拍照很麻烦,于是找了很多文章,居然没有人提到,只好FQ去找 ...

  5. c++ 前置++与后置++的区别

    用C++编程的都知道,C++提供了一个非常强大的操作符重载机制,利用操作符重载,我们可以为我们自定义的类增加更多非常有用的功能.不过,C++也有限制,就是当我们为自定义的类重载操作符时,重载操作符的含 ...

  6. C++之运算符重载(前置++和后置++)

    今天在阅读<google c++ 编程风格>的文档的时候,5.10. 前置自增和自减:有一句话引起了我的注意: 对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.,理 ...

  7. C++中前置操作符和后置操作符的重载

    1,C 语言中讨论了原生含义,C++ 中有必要考虑前置.后置操作符能够重载,有何问题: 2,值得思考的问题: 1,下面的代码有没有区别?为什么? 1,i++  // i 的值作为返回值,i 自增 1: ...

  8. android Camera 如何判断当前使用的摄像头是前置还是后置

    现在 android 平台的智能手机一般都标配有两颗摄像头.在 Camera 中都存在摄像头切换的功能. 并且有一些功能前后置摄像头上会有所不同.譬如人脸检测,人脸识别,自动对焦,闪光灯等功能, 如果 ...

  9. pytest_前置后置

    今天总结下pytest,pytest简直就是python自动化中的高富帅,各种操作,哈哈 这次总结主要涉及到了以下几点: 1.unittest中的setUp.tearDown.setUpClass.t ...

随机推荐

  1. Oracle12C创建视图权限不足

    授权: GRANT CREATE VIEW TO c##scott; 作者:彼岸舞 时间:2020\06\23 内容关于:Oracle 本文属于作者原创,未经允许,禁止转发

  2. SQL Builder 1.04

    解析效果: select id,code,name,utime,src,ctime from stock where id<20 and code like '%6%' order by id, ...

  3. 11.QT-ffmpeg+QAudioOutput实现音频播放器

    1.前言      由于QAudioOutput支持的输入数据必须是原始数据,所以播放mp3,WAV,AAC等格式文件,需要解封装后才能支持播放.      而在QT中,提供了QMediaPlayer ...

  4. hacker101 CTF 学习记录(二)

    前言 无 Easy-Postbook 拿到功能有点多,先扫一遍目录 .Ds_Store没有啥东西,page是个静态页面 随便注册个账号,登录后已经有2篇文章,第一篇文章的id是1 自己创建文章,将ur ...

  5. 高可用服务之Keepalived利用脚本实现服务的可用性检测

    上一篇博客主要聊到了keepalived高可用LVS集群的相关配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13659428.html:keepalive ...

  6. 不懂 ZooKeeper?没关系,这一篇给你讲的明明白白

    本来想系统回顾下 ZooKeeper的,可是网上没找到一篇合自己胃口的文章,写的差不多的,感觉大部分都是基于<从Paxos到ZooKeeper 分布式一致性原理与实践>写的,所以自己读了一 ...

  7. HBase启用压缩

    1. 压缩算法的比较 算法 压缩比 压缩 解压 GZIP 13.4% 21MB/s 118MB/s LZO 20.5% 135MB/s 410MB/s Snappy/Zippy 22.2% 172MB ...

  8. Docker实战(7):Docker无日志(无*-json.log文件)

    出现这种情况基本都是docker 版本太旧,我的处理方案就是将docker 版本升级到最新,然后重新docker run 一遍就会有了.注意:docker 升级后,原来images,容器会出现一些小问 ...

  9. firewalld 防火墙

    firewalld防火墙   firewalld简述 firewalld:防火墙,其实就是一个隔离工具:工作于主机或者网络的边缘对于进出本主机或者网络的报文根据事先定义好的网络规则做匹配检测,对于能够 ...

  10. 首发!Alibaba内部:Spring源码培训课件笔记曝光!

    本文包含的内容 Spring占有的市场 阅读源码的重要性 阅读源码困难度 课件笔记的主要内容 Spring占有的市场 先来简单说一下现在各个企业常用并与Spring相关的: ssh = spring ...