优先使用++和–的前缀形式
灵动阳光: http://www.sssit.org/blog/articles/203.html
C/C++的++和--操作符既有前缀形式也有后缀形式,而两种形式的语义又是略有区别的。
习惯上我们总是用先+1还是后+1来区分它们,习惯上我们总是用它们的后缀形式。
通过以下面的分析与测试,我们会发现:在写代码时,优先使用++和—的前缀形式是一个很好的习惯。
前缀形式和后缀形式的区别
前缀形式的++和—操作符与后缀形式的本质区别是:
后缀形式返回的是自增或自减后的原值;
而前缀形式对原值进行自增或自减操作,然后返回自增或自减操作前新值,并且后缀形式是基于前缀形式实现的。
这个看一下operator++和operator--的代码就知道了,有代码有真相。
下面是 ++ 和 -- 的前缀实现形式
T& T::operator++(){
// 在这儿执行递增操作
return *this;
}
T& T::operator--(){
// 在这儿执行递减操作
*this;
}
下面是 ++ 和 -- 的后缀实现形式
T T::operator++(int) {
T old(*this);
++*this;
return old;
}
T T::operator--(int){
T old(*this);
--*this;
return old;
}
从上面的代码可以看到,
前缀形式的实现是 先执行递增或递减操作,然后引用返回原对象;
后缀形式的实现是 创建临时对象 old, 并用原值进行初始化,再对原值执行递增或递减操作, 然后再返回 old给你用, 返回的时候又会创建一个匿名的对象。
因此后缀形式比前缀形式多两次临时变量创建和两次临时变最销毁的开销。
一个例子
如果++或--的对象不是基本数据类型,这个开销可能会比较大,这个可以通过下面的例子说明:
下面是两个测试方法,它们的实参都是size为10000000的std::list<int>:
void test1(list<int>& l)
{
list<int>::iterator it = l.begin();
for (; it != l.end(); it++)
{
int v = *it;
}
}
void test2(list<int>& l)
{
list<int>::iterator it = l.begin();
for (; it != l.end(); ++it)
{
int v = *it;
}
}
在工作的PC上粗略的统计了一下,test1用了61秒,test2用了30秒。
结论
对于非基本数据类型、对于大量的操作,++和—的前缀形式比后缀形式的效率要高一些,所以在写代码时,除非确实需要用后缀形式返回原值,否则要优先使用++和--的前缀形式。
参考
<< C++编程规范:101条规则、准则与最佳实践 >>