前置操作符和后置操作符
首先来思考一个问题:
//下面的代码有没有区别?为什么?
i++; // i的值作为返回值,i 自增 1
++i; // i自增 1, i 的值作为返回值
如果从原生语义上讲,不一样,但是是在单条语句内,运算结果都一样。并且如果在单条语句内,编译器会进行优化,有的是作为原生语义来进行编译,有的是直接作为同一意思来进行的。
- 所以:
- 现代编译器产品会对代码进行优化
- 优化使得最终的二进制程序更加高效
- 优化后的二进制程序丢失了C/C++的原生语义
- 不可能从编译后的二进制程序还原C/C++程序
重载操作符
那这里再深入一下,讨论另外一个问题:
++ 操作符可以重载吗?
如何区分前置++ 和 后置++?
答案是可以重载的,不光是基本类型可以重载,类类型也可以重载。
- ++操作符可以被重载
- 全局函数和成员函数均可以进行重载
- 重载前置 ++ 操作符不需要额外的参数
- 重载后置 ++ 操作符需要一个 int 类型的占位参数
例如:
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test(int i)
{
mValue = i;
}
int value()
{
return mValue;
}
// 重载前置 ++ 操作符,不需要参数
Test& operator ++ ()
{
++mValue;
return *this;
}
//重载后置 ++操作符,需要一个int类型的参数
Test operator ++ (int)
{
Test ret(mValue);
mValue++;
return ret;
}
};
int main()
{
Test t(0);
//这里通过重载操作符,直接可以实现类类型的自加
t++;
++t;
return 0;
}
看完代码,其实也可以再次回答刚开始的问题了:
- 区别:
- 对于基础类型的变量
- 前置 ++ 的效率与后置 ++ 的效率基本相同
- 根据项目组编码规范进行选择
- 对于类类型的对象
- 后置 ++的重载函数中需要 新创建一个临时对象,随即又要销毁
- 前置 ++的重载函数中不需要创建对象
- 所以 前置 ++ 的效率高于后置 ++
- 尽量使用前置 ++ 操作符提高程序效率
- 对于基础类型的变量
注意
看完 ++ 操作符的重载以后,其实也可以推出 -- 操作符和 ++ 操作符的重载规则是一样的,所有适用于 ++ 操作符的规则和特性也同样适用于 -- 操作符。
小结
- 编译优化使得最终的可执行程序更加高效
- 前置 ++ 操作符和后置 ++ 操作符都可以被重载
- ++ 操作符的重载必须符合其原生语义
- 对于基础类型,前置 ++ 与后置 ++ 的效率几乎相同
- 对于类类型,前置 ++ 的效率高于后置 ++
- ++ 操作符的重载规则和特性同样也适用于 -- 操作符
网友评论