C/C++从自增运算符重载看“a++++”非法操作

引言:在学习C/C++自增自减(本文以自增运算符为例)运算符的时候,都知道有前置和后置两种写法,假设a是一个整形变量。我们都知道,以下写法是正确的:+++a;而以下写法:a+++却是错误的,然而很多教科书并未给出底层原理,今天我们就从运算符的重载入手剖析后置递增运算符为什么不可以用a+++这种写法。

现在,假设我们有一个MyInteger类,意为我们自己定义的整形类:

class MyInteger{
private:
int num;
public:
MyInteger(){
num=10;
}
};

并且我们实例化一个该类的对象:
MyInteger in{ };
并试图对其进行自增操作,并打印,这里就要涉及到打印自定义数据类型和自增自定义数据类型的操作,因此要用到运算符的重载:
下面开始对<<(左移运算符)进行全局重载:

ostream& operator<<(ostream & cout,  MyInteger in){ /*注意这里第二个参数不能使用引用传参,否则后
置递增(递减)无法正常实现*/
   cout<<in.num<<endl;
return cout;
}

接下来我们考虑用成员函数重载MyInteger类型的自增运算:
先考虑前置自增的特性:即先把变量+1后再拿来使用。故我们直接返回的应是已经自增完后的变量。
首先重载前置自增:由于自增完数据类型仍然是MyInteger,且为了保证递增后要返回调用的对象本身(否则无法实现多次递增且报错),故返回值类型应该是MyInteger的引用类型

MyInteger& operator++(){
       this->num+=1;
return *this;//返回调用函数的对象本身
}

接下来考虑实现重载后置自增运算符:先考虑后置自增的特性:先把原有的数值拿来使用,使用完毕后再+1。因此我们考虑在重载函数中构建一个临时变量用以存储未自增前的变量值,之后再让变量本身自增一个单位,最后返回临时变量。

MyInteger operatorint//这里使用占位参数,且只能是int类型用以区分两个重载函数,
{
   MyInteger temp=*this;
   this->num+=1;
return temp; /*注意这里返回的是一个值而非引用,为什么呢?原因就在于这里返回的是一个临时变量,
在函数运行完毕后会被销毁,如果再返回引用便成了非法操作!!而这里恰恰就是我们今天要讲的内容,
C/C++的后置自增运算符实现原理和我们这里的函数一模一样,函数运行完后返回的是一个常量,
而非像前置自增那样的引用,所以无法对常量进行修改,也就无法实现a+++这种操作了。*/
}

总结:前置递增返回引用,后置递增返回值。
除此之外,运算符的重载仍然有许多值得留意的细节,这些细节稍有不注意就会酿成灾难性后果,
**比如前置自增返回值必须是对应类型的引用类型,左移运算符的返回值类型必须是ostream类型的引用类型(链式编程思想),否则无法实现连续打印等等,**总之,和java等其他语言相比,C/C++语言有非常多的细节需要注意,但这也有助于我们了解一门编程语言的底层实现原理,能更加考查大家的细心程度和编码能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值