遍历map的2中方式

来源:互联网 发布:淘宝店铺申诉入口 编辑:程序博客网 时间:2024/05/16 07:46


看了很多遍历map的文章,里面的代码有很多,但是也让我很疑惑。想知道遍历到底是下面两种的哪一种? 
for(iterator it = begin(); it != end(); ++it) 

或者 
for(iterator it = begin(); it != end(); it++) 

如果这两种都对的话,区别是什么呢??

对于两种方式来说: 
for(iterator it = begin(); it != end(); ++it) 

return it->second; 


for(iterator it = begin(); it != end(); it++) 

return it->second; 

每一次返回的结果是否相同??

最佳答案
两种方式iterator遍历的次数是相同的,但在STL中效率不同前++--返回引用,后++--返回一个临时对象,因为iterator是类模板,使 用it++这种形式要返回一个无用的临时对象,而it++是函数重载,所以编译器无法对其进行优化,所以每遍历一个元素,你就创建并销毁了一个无用的临时 对象。 

不信的话你可以去看看C++的标准库,还有符合标准C++的教材,除了特殊需要和对内置类型外,基本都是使用++it来进行元素遍历的,不管是源代码还是教材中都是如此。 

用户定义类型对操作符的重载应与内置操作符的行为相似,而且后自增/减往往是引用前自增/减来作为其实行的一个副本。 

比如通常都是这种形式: 

class foo 

public: 
foo& operator ++ (){return ++bar;} 

foo operator ++ (int) 

foo tmp = *this; // 创建临时对象 ★ 
++*this; // 调用前自增 
return tmp; // 返回临时对象 ★ 


private: 
int bar; 


以上标★号的2个步骤有时是多余的,比如用STL中用iterator遍历容器,这样就造成了不必要的程序效率的损失。 

这也是被一些从C移植到C++的程序员所频频忽视的细节,所以它们被称为从C带到C++中的编程恶习。 

More Effective C++ 
Item 6: Distinguish between prefix and postfix forms of increment and decrement operators. 

对C++中的前/后自增/减操作符以及因C++的重载对他们所引发的效率问题有详细的讲解。以下是一部分内容: 

If you're the kind who worries about efficiency, you probably broke into a sweat when you first saw the postfix increment function. That function has to create a temporary object for its return value (see Item 19), and the implementation above also creates an explicit temporary object (oldValue) that has to be constructed and destructed. The prefix increment function has no such temporaries. This leads to the possibly startling conclusion that, for efficiency reasons alone, clients of UPInt should prefer prefix increment to postfix increment unless they really need the behavior of postfix increment. Let us be explicit about this. 

When dealing with user-defined types, prefix increment should be used whenever possible, because it's inherently more efficient. (注意这一句) 

Let us make one more observation about the prefix and postfix increment operators. Except for their return values, they do the same thing: they increment a value. That is, they're supposed to do the same thing. How can you be sure the behavior of postfix increment is consistent with that of prefix increment? What guarantee do you have that their implementations won't diverge over time, possibly as a result of different programmers maintaining and enhancing them? Unless you've followed the design principle embodied by the code above, you have no such guarantee. That principle is that postfix increment and decrement should be implemented in terms of their prefix counterparts. You then need only maintain the prefix versions, because the postfix versions will automatically behave in a consistent fashion.




0 0
原创粉丝点击