上班 看到有网站推送的邮件
看来n多后有个问题吸引了我下,下面分享下:
请问,(a++)++,(++a)++,++(a++),++(++a)能够编译通过么?如果可以,那么运行之后a的值是多少?如果不能,为什么?
这个看起来很简单的问题,我以为一次性猜出答案,后来发现我错了!
这个其实是和编译器有关的。
那么以VS2008为例来说吧~
上述代码的编译结果:
1>------ 已启动生成: 项目: test30, 配置: Debug Win32 ------
1>正在编译...
1>main.cpp
1>g:\workspace\exercise\cppprimer\test30\test30\main.cpp(8) : error C2105: “++”需要左值
1>g:\workspace\exercise\cppprimer\test30\test30\main.cpp(12) : error C2105: “++”
即(a++)++;和++(a++);会编译出错,其他的通过编译。原因如下:
后置++返回右值,而前置++返回左值。
其实,看下前置和后置++的实现就知道的很清楚了,这是从《C++ Primer(第三版)》上摘下来的一段代码,是实现对复数对象的操作符重载:
前置:
inline complex<double>&
operator++(complex<double> &cval)
{
return cval += complex<double>(1);
}
后置:
inline complex<double>
operator++(complex<double> &cval,int)
{
complex<doble> oldval = cval;
cval += complex<double>(1);
return oldval;
}
你会发现,前置++是返回的左值,而后置++返回的是一个局部变量,是右值。
再举一个例子,假设有一个类Age,描述年龄。该类重载了前置++和后置++两个操作符,以实现对年龄的自增。
1. class Age
2. {
3. public:
4.
5. Age& operator++() //前置++
6. {
7. ++i;
8. return *this;
9. }
10.
11. const Age operator++(int) //后置++
12. {
13. Age tmp = *this;
14. ++(*this); //利用前置++
15. return tmp; //注意:返回的是临时对象
16. }
17.
18. Age& operator=(int i) //赋值操作
19. {
20. this->i = i;
21. return *this;
22. }
23.
24. private:
25. int i;
26. };
从上述代码,我们可以看出前置++和后置++,有4点不同:
- 返回类型不同
2. 形参不同
3. 代码不同
4. 效率不同
返回值类型的区别前置++的返回类型是Age&,后置++的返回类型const Age。这意味着,前置++返回的是左值,后置++返回的是右值。
左值和右值,决定了前置++和后置++的用法。
1. int main()
2. {
3. Age a;
4.
5. (a++)++; //编译错误
6. ++(a++); //编译错误
7. a++ = 1; //编译错误
8. (++a)++; //OK
9. ++(++a); //OK
10. ++a = 1; //OK
11. }
a++的类型是const Age,自然不能对它进行前置++、后置++、赋值等操作。
++a的类型是Age&,当然能对它进行前置++、后置++、赋值等操作。
转载于:http://www.dewen.org/q/7318/?utm_source=weekly_32607189_31&utm_field=5&utm_id=7
原文链接: https://www.cnblogs.com/AspJS/archive/2012/11/09/2762138.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/68791
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!