📄 item_076.htm
字号:
<h3><span lang=EN-US>76. </span><span style='font-family:宋体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial'>默认情况下使用</span><span lang=EN-US>vector</span><span
style='font-family:宋体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial'>。否则选择其它合适的容器。</span></h3>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>摘要</span></b></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>使用“正确的容器”很棒:如果你有很好的理由去使用某个特定类型的容器,那么就使用该容器,但是要清楚自己的选择是正确的。</span></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>使用</span><span lang=EN-US>vector</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>也一样:否则的话,应该继续使用</span><span lang=EN-US>vector</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>而不要有什么踌躇,但是仍然要清楚自己的选择是正确的。</span></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>讨论</span><a name=ch75index09></a><a name=ch75index08></a><a
name=ch75lev1sec2></a><span lang=EN-US><o:p></o:p></span></b></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>下面是三个基本问题和相关提问,针对一般编程,尤其是容器的选择:</span></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<ul style='margin-top:0cm' type=disc>
<li class=MsoNormal style='mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>在编程时首先保证正确,简单和清晰(参见第</span><span lang=EN-US>6</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>条):尽量选择能使你编写最清晰的代码的容器。例如:如果你需要在某个特定的位置执行插入操作,那么请使用顺序型容器(</span><span
lang=EN-US>sequence container</span><span style='font-family:宋体;
mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:"Times New Roman"'>)(例如:</span><span
lang=EN-US>vector</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,</span><span
lang=EN-US>list</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>)。如果你需要随机存取的迭代器,那么请使用</span><span
lang=EN-US>vector</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,</span><span
class=SpellE><span lang=EN-US>deque</span></span><span style='font-family:
宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,或者</span><span
lang=EN-US>string</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>。如果你需要类似字典的查找,如</span><span
lang=EN-US>c[0] = 42;</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,那么请使用关联型容器(例如</span><span
lang=EN-US>set</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,</span><span
lang=EN-US>map</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>),但是如果你需要一个有序关联型容器,那么你不能使用基于哈希表(不标准的</span><span
lang=EN-US>hash_...</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>或标准的</span><span
lang=EN-US>unordered_...</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>)的容器。</span></li>
</ul>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<ul style='margin-top:0cm' type=disc>
<li class=MsoNormal style='mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>仅在必需时才考虑效率(参见第</span><span lang=EN-US>8</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>条):如果查找速度是一个关键的考虑因素,那么应该根据实际的性能数据,优先使用基于哈希表(不标准的</span><span
lang=EN-US>hash_...</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>或标准的</span><span
lang=EN-US>unordered_...</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>)的容器,然后是有序的</span><span
lang=EN-US>vector</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,再然后是</span><span
lang=EN-US>set</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>或</span><span
lang=EN-US>map</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,通常是这样的次序。即便如此,只有在容器大到能淹没常数因子的时候,</span><span
lang=EN-US>Big-Oh</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>的性能差异才会体现出来,而对小型对象(如</span><span
lang=EN-US>double</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>)的容器来说,这通常都不会发生,除非容器中的元素超过数千个。</span></li>
</ul>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<ul style='margin-top:0cm' type=disc>
<li class=MsoNormal style='mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>尽可能编写类似事务处理的,在出现错误时也能够严格保证安全的代码(参见第</span><span
lang=EN-US>71</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>条),不要使用无效对象(参见第</span><span
lang=EN-US>99</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>条):如果需要插入和移除元素的操作具有事务处理的语义,或者需要尽量避免使迭代器作废,那么应该优先选择基于节点的容器(例如:</span><span
lang=EN-US>list</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,</span><span
lang=EN-US>set</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,</span><span
lang=EN-US>map</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>)。</span></li>
</ul>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>否则,应该遵循</span><span lang=EN-US>C++</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>标准的建议:“</span><span lang=EN-US>vector</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>是应该在默认情况下使用的顺序型容器。”</span> <span lang=EN-US>([C++03]
§23.1.1)</span></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>如果你对此建议持怀疑态度,那么请扪心自问是否真的有令人信服的理由不去使用标准库中唯一能够保证下面所有性质的容器。</span><span
lang=EN-US>vector</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>能够:</span></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<ul style='margin-top:0cm' type=disc>
<li class=MsoNormal style='mso-list:l1 level1 lfo3;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>保证在任何容器中具有最低的空间开销(每个对象零字节)。</span></li>
<li class=MsoNormal style='mso-list:l1 level1 lfo3;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>保证在任何容器中对容器内的元素具有最快的存取速度。</span></li>
<li class=MsoNormal style='mso-list:l1 level1 lfo3;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>保证具有很好</span><span lang=EN-US>locality of reference</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>,也就是说保证容器中相邻的对象在内存中也是相邻的,而标准库中的任何其它容器都无法保证这一点。</span></li>
<li class=MsoNormal style='mso-list:l1 level1 lfo3;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>保证内存布局与</span><span lang=EN-US>C</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>兼容,这一点和标准库中的任何其它容器都不同。(参见第</span><span lang=EN-US>77</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>和</span><span lang=EN-US>78</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>条)</span></li>
<li class=MsoNormal style='mso-list:l1 level1 lfo3;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>保证在任何容器中具有最灵活的迭代器(随机存取迭代器)。</span></li>
<li class=MsoNormal style='mso-list:l1 level1 lfo3;tab-stops:list 36.0pt'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>几乎肯定具有最快的迭代器(指针,或与之性能相当的迭代器类,在非调试模式下可以被编译成具有同等的速度),比所有其它容器的迭代器都快。</span></li>
</ul>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>有什么理由在默认的情况下不使用这样的容器吗?如果你确实有理由,而且是因为你对本节一开始提到的三个问题所作出的回答,那么你的选择是对的,非常好——你可以使用其它的容器,但是要清楚自己的选择是正确的。如果你没有什么理由,那么就继续使用</span><span
lang=EN-US>vector</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>而不要有什么踌躇,但是仍然要清楚自己的选择是正确的。</span></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>最后,与特定厂商提供的代码或自己手工编写的代码相比,要尽量使用标准库的容器和算法。</span></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><a name=ch74lev1sec3></a><b style='mso-bidi-font-weight:
normal'><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>示例</span></b></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><i style='mso-bidi-font-style:normal'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>例如:</span><span lang=EN-US>vector</span></i><i
style='mso-bidi-font-style:normal'><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>用于小的列表。</span></i><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>仅仅因为“对于列表操作而言</span><span lang=EN-US>list</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>显然是正确的类型”就使用</span><span lang=EN-US>list</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>是一个常见的错误,例如在序列的中间执行插入操作。对一个小型列表使用</span><span lang=EN-US>vector</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>几乎总是比使用</span><span lang=EN-US>list</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>要好。即便对</span><span lang=EN-US>vector</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>来说在序列的中间插入元素是线性时间的操作,而对</span><span lang=EN-US>list</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>来说却是常数时间的操作,在容器相对较小的情况下,</span><span lang=EN-US>vector</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>通常优于</span><span lang=EN-US>list</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>,这是因为它具有较佳的常数因子,而</span><span lang=EN-US>list</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>的</span><span lang=EN-US>Big-Oh</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>优势只有在数据的大小变得比较大的时候才能体现。</span></p>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>这里,应该始终使用</span><span lang=EN-US>vector</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>,除非因为数据大小的原因需要其它的选择(参见第</span><span lang=EN-US>7</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>条),或者因为强安全保证至关重要并且容器元素的类型的复制构造函数和复制赋值操作符可能会失败(</span><span
lang=EN-US>list</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>对这些类型的元素集合的插入操作提供了强安全保证,在这种情况下,这一点可能很重要)。</span></p>
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -