用C++编程的都知道,C++提供了一个很是强大的操做符重载机制,利用操做符重载,咱们能够为咱们自定义的类增长更多很是有用的功能。不过,C++也有限制,就是当咱们为自定义的类重载操做符时,重载操做符的含义应该跟内置类型同样,好比,你不能经过重载+号操做符来实现两个数相乘的运算,实现须要是两个数相加的运算。本篇,我重点介绍下重载前置++和后置++的区别(前置--跟后置--相似)。c++
咱们知道,写for循环年的时候,能够用下面这两种方式: 编程
for(int i=0; i<10; i++) { //do something } for(int j=0; j<10; ++j) { //do something }
如上两种方式,i++跟++j到底有什么区别呢?函数
首先,这两种方式都会使得i跟j自增1, 不一样的地方在于其内部实现; i++的实现原理是现将i自增1,而后返回i的引用(咱们知道重载操做符也是能够有返回值的);而++j的实现原理是:先定义一个j的副本,而后在将j自增1,最后返回以前定义个那个副本的值。this
一般,c++的内置类型都要求前缀式操做符返回被增量或被减量对象的引用;而要求后缀式操做符返回被增量活被减量对象作增或减操做以前的副本(这里边就存在内存拷贝)。spa
实际的调用过程看起来应该是这样:code
for( int i=0; i<10; i.operator++(0) ) { //调用后置++ //do something } for( int i=0; i<10; i.operator++() ) { //调用前置++ //do something }
看到这里,你可能 有个疑问,为何调用后置++的以后,参数列表要传一个0而前置++却没有传呢?对象
这里就牵扯出前置++跟后置++的另外一个差异。blog
前置++和后置++在定义的都是同样,看起来应该是下边这样:内存
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 : --操做符的前缀式和后缀式类型)