Effective STL 条款17

原创 2004年02月26日 14:51:00

Item17 使用"swap诡计"来修去多余的空位

假设现在你正在为电视游戏节目"Give Me Lots Of Money--Now!"写一个支持软件.你一直记录着潜在的竞争者,
你把他们保存在一个vector中:

class Contestant {...};
vector<Contestant> contestants;

当节目组选择新的竞争者,它会被申请信淹埋,而你的vector将很快申请很多元素. 当节目制作人挑选期望的竞争
者,当然只有很少一部分竞争者来到vector的前部(也许通过partial_sort或partition参考Item31),不需要的竞争
者将被删除出vector(典型地使用区间删除,参考Item5).它可以很好的减小vector的大小(size),但对vector的空间
(capacity)不起任何作用.如果vector一次包含了10万个竞争者,它的空间将保持最少100000,即使后来它只保存,嗯,
也许10个.

为了避免vector占用它不再使用的空间,你需要减少它的空间,从它用过的最大空间到它现在仅需的空间.这种
空间减少通常称为"收缩至合适"(shrink to fit).收缩至合适易于编程,但是代码是--如何实现--事情并非如
直觉所想.让我先展示它,等一下再说明.

这是如何从竞争者vector中修去多余空位的方法:

vector<Contestant>(contestants).swap(contestants);

表达式vector<Contestant>(contestants)创建一个临时的vector,它是contestants的拷贝:vector的拷贝构造函数
完成这一工作.但是vector的拷贝构造函数仅申请适合需要的空间来复制.因此临时vector不包含多余空位.然后
交换临时对象和contestants的数据,结果临时对象包含着过多的空间,这些空间曾经是contestants的,
最后,临时对象销毁,并释放空间.Yes,收缩至合适.

同样的技巧也适用于string:

string s;
…   //make s large, then erase most
  //of its characters
string(s).swap(s); // do a "shrink-to-fit" on s

现在, 语言警察要求我通知你,并没有什么人保证这一技巧真的减少了多余的空间.实现可以自由的赋与vector或string
多余的空间,如果它愿意,并且有时它确实愿意.例如,有一个最小的空间值,低于此值,将不再减少.也可能强制要求
vector和string的空间必须是二的倍数.(根据我的经验, 这种不规则的要求,在string的实现中更常见,而不是vector)
例如Item15).这种方法的收缩至合适并不表示"使用空间尽可能的小",它表示"使用空间尽实现愿意,达到的当前容器大小
换一个STL实现也许更小,但是,这是你能做地最好情况.因此当你想起vector或stirng的"收缩至合适",想想"swap诡计"

另一方面,一个"swap诡计"的变体可以用于即清空容器又减少它的大小至实现许可的范围.简单地与默认构造函数生成
的临时对象交换数据即可:

vector<Contestant> v;
string s;
…     // use v and s
vector<Contestant>().swap(v);   //clear v and minimize its capacity
string().swap(s);   // clear s and minimize its capacity

最后一次观察"swap诡计", 或者说是,通用的swap.交换两个容器的内容,包括交换它们的迭代器,指针和引用.在一个容器中
迭代器,指针和引用,在变换后的另一个容器中仍有效并指向同一个元素.

 

effective stl 第19条:理解相等(equality)和等价(equivalence)的区别

#include #include #includeusing namespace std;bool ciStringCompare(const string l, const string r) {...
  • u014110320
  • u014110320
  • 2016年09月20日 23:36
  • 236

《Effective C++》设计与声明:条款18-条款19

这两个条款讲的是:接口的设计和类的设计。其中接口的设计原则是让接口容易被正确使用,不容易被误用;后面有一系列的做法。类的设计,讲的是类设计犹如新类型type的设计。在设计类时要考虑的一系列问题。...
  • KangRoger
  • KangRoger
  • 2015年01月21日 21:43
  • 1319

《Effective C++》学习笔记——条款31

《Effective C++》学习笔记——条款31:将文件间的编译依存关系降至最低
  • lx417147512
  • lx417147512
  • 2015年06月15日 13:51
  • 1364

《Effective C++》学习笔记——条款25

《Effective C++》学习笔记——条款25:考虑写出一个不抛异常的 swap 函数
  • lx417147512
  • lx417147512
  • 2014年12月30日 22:32
  • 836

《Effective C++》:条款41-条款42

条款41了解隐式接口和编译期多态 条款42了解typename的双重意义条款
  • KangRoger
  • KangRoger
  • 2015年03月10日 22:13
  • 1200

《Effective C++》:条款28-条款29

条款28避免返回handles指向对象内部成分:指的是不能返回对象内部数据/函数的引用、指针等。 条款29为异常安全而努力是值得的:指的是要有异常处理机制,避免发生异常时造成资源泄露等问题。...
  • KangRoger
  • KangRoger
  • 2015年02月19日 19:47
  • 1370

《Effective C++》资源管理:条款13-条款15

在系统中,资源是有限的,一旦用完必须归还给系统,否则可能会造成资源耗尽或其他问题。例如,动态分配的内存如果用完不释放会造成内存泄漏。 这里说的资源不仅仅是指内存,还包括其他,例如文件描述符、网络连接、...
  • KangRoger
  • KangRoger
  • 2015年01月14日 21:46
  • 1282

《Effective C++》让自己习惯C++:条款1-条款4

《Effective C++》条款1到条款4。基本是总结C++的一些特点,尤其是不同于C语言的特点。...
  • KangRoger
  • KangRoger
  • 2014年12月13日 19:26
  • 2344

Effective Modern C++ 条款28 理解引用折叠

Effective Modern C++ 条款28
  • big_yellow_duck
  • big_yellow_duck
  • 2016年09月04日 19:34
  • 1985

《Effective C++》:条款44-条款45

条款44将与参数无关的代码抽离templates 条款45运用成员函数模板接受所有兼容类型...
  • KangRoger
  • KangRoger
  • 2015年03月12日 22:01
  • 1482
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Effective STL 条款17
举报原因:
原因补充:

(最多只允许输入30个字)