码迷,mamicode.com
首页 > 其他好文 > 详细

[CPP - STL] swap技巧

时间:2015-05-10 23:36:23      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:

最近在看《Effective STL》【条款17:使用交换技巧修整过剩容量】中提到容器的成函数void swap(container& from),即实现容器对象与from对象的交换。

另外,对于连续内存容器vector和string,还有shrink to fit(收缩到合适,根据容器的实际size设置capacity,减少实际内存分配)的功能。

以vector为例,首先说下,size和capacity、resize和reserve的含义及区别。

一、sizecapacityresizereserve

size:对象的元素个数,除reserve外的几乎所有vector操作都可以影响size;

capacity:容器预留容量,即占用真实内存量,capacity >= size。push_back、insert、resize、reserve操作可以影响capacity,其特点为只增不减(即使erase和clear操作);

resize:可以改变size,如果resize的元素个数大于capacity,则同时改变capacity,增加对象内存空间;

reserve:不改变size,如果reserve的元素个数大于capacity,则改变capacity,增加对象内存空间,反之,则不影响capacity;

代码示例如下

 1 #include <iostream>
 2 #include <vector>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     vector<int> v;
 9     cout << "initial: "                         << endl;
10     cout << "size of v is     " << v.size()     << endl;
11     cout << "capacity of v is " << v.capacity() << endl << endl;
12 
13     v.insert(v.end(), 10, 1);
14     cout << "after insert:  "                   << endl;
15     cout << "size of v is     " << v.size()     << endl;
16     cout << "capacity of v is " << v.capacity() << endl << endl;
17 
18     v.erase(v.end()-5, v.end());
19     cout << "after erase:  "                    << endl;
20     cout << "size of v is     " << v.size()     << endl;
21     cout << "capacity of v is " << v.capacity() << endl << endl;
22 
23     v.reserve(20);
24     cout << "after reserve:  "                  << endl;
25     cout << "size of v is     " << v.size()     << endl;
26     cout << "capacity of v is " << v.capacity() << endl << endl;
27 
28     v.resize(15);
29     cout << "after resize:  "                   << endl;
30     cout << "size of v is     " << v.size()     << endl;
31     cout << "capacity of v is " << v.capacity() << endl << endl;
32 
33     v.reserve(10);
34     cout << "after reserve:  "                  << endl;
35     cout << "size of v is     " << v.size()     << endl;
36     cout << "capacity of v is " << v.capacity() << endl << endl;
37 
38     v.clear();
39     cout << "after clear:  "                    << endl;
40     cout << "size of v is     " << v.size()     << endl;
41     cout << "capacity of v is " << v.capacity() << endl << endl;
42 
43     return 0;
44 }

输出结果为:

initial:
size of v is     0
capacity of v is 0

after insert:
size of v is     10
capacity of v is 10

after erase:
size of v is     5
capacity of v is 10

after reserve:
size of v is     5
capacity of v is 20

after resize:
size of v is     15
capacity of v is 20

after reserve:
size of v is     15
capacity of v is 20

after clear:
size of v is     0
capacity of v is 20

根据上面几个概念及Demo,可以看出来,vector对象的实际内存(即capacity)在多次insert和erase操作后大于实际元素个数(size),即使在clear操作后,capacity依然不会减小为零。

所以,有必要对这种基于内存池的容器做内存收缩。

二、swapshrink to fit

修改vector对象多余内存空间的方法:

vector<int>(v).swap(v); // v为一个vector对象

vector<int>(v)基于v拷贝构造了一个临时vector,其分配了v.size()个元素的内存空间,即capacity为v.size(),然后vector<int>(v)与v交换数据,交换后,v的capacity也减少为v.size(),而临时vector对象vector<int>(v)被销毁。

另外,vector<int>().swap(v); // 可以清除v的内存空间

代码示例如下

 1 #include <iostream>
 2 #include <vector>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     vector<int> v(10, 1);
 9     cout << "initial: "                         << endl;
10     cout << "size of v is     " << v.size()     << endl;
11     cout << "capacity of v is " << v.capacity() << endl << endl;
12 
13     v.erase(v.end()-5, v.end());
14     cout << "after erase:  "                    << endl;
15     cout << "size of v is     " << v.size()     << endl;
16     cout << "capacity of v is " << v.capacity() << endl << endl;
17 
18     vector<int>(v).swap(v);
19     cout << "after swap (shrink to fit):  "     << endl;
20     cout << "size of v is     " << v.size()     << endl;
21     cout << "capacity of v is " << v.capacity() << endl << endl;
22 
23     vector<int>().swap(v);
24     cout << "after swap (clear):  "             << endl;
25     cout << "size of v is     " << v.size()     << endl;
26     cout << "capacity of v is " << v.capacity() << endl << endl;
27 
28     return 0;
29 }

输出结果为:

initial:
size of v is     10
capacity of v is 10

after erase:
size of v is     5
capacity of v is 10

after swap (shrink to fit):
size of v is     5
capacity of v is 5

after swap (clear):
size of v is     0
capacity of v is 0

如果使用C++11及更新标准的话,可以直接使用shrink_to_fit函数。

 

[CPP - STL] swap技巧

标签:

原文地址:http://www.cnblogs.com/yongpenghan/p/4493300.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!