点击查看Evernote原文。
#@author: gr
#@date: 2014-09-15
#@email: forgerui@gmail.com
Chapter2 vector和string
Topic 15: 注意string
实现的多样性
string
可能有多种不同的实现。文中介绍了四种,由于采用不同的实现,使用sizeof(string)
计算会得到不同的值。
在这四种实现中,string
对象的大小可以是一个char*
指针大小的1到7倍。并且,各种实现的动态内存分配也不尽相同,可能需要1到2次的动态内存分配。
例子 :
其中一种实现提供了对小字符串的性能优化。首先,这个string
占据了7倍char*
的空间,是实现中空间最大的,其中有4倍空间是用来存储字符,最多15个字符,这样当字符小于16个时,不需要动态分配内存;如果,超过15个字符,则会动态分配内存,并将地址存储在x4空间的顶端。
Topic 17: 使用swap技巧
除去多余的容量
vector
使用reserve
预先申请空间时,可能申请的很大,如何去除多余的空间呢。使用swap
技巧可以有效解决这个问题。用已有vector
去初始化一个临时向量,并进行交换,最后交换后临时向量被析构(先前的已有向量)。注意,这里的除去多余容量不是全部空余向量,因为编译器可能保持一些空间以保证空间为2的乘幂数。
同样,也可以使用swap
技巧去清空vector
和string
。
vector<int> vi;
vi.reserve(100000);
//....插入元素操作
//使用swap交换
vector<int>(vi).swap(vi);
//清空
vector<int>().swap(vi);
string str("afdsaf");
string().swap(str);
Topic 18: 避免使用vector<bool>
使用vector<bool>
可能和你期望得到的结果不同,它不能称得上真正的容器。一般取得一个容器元素的地址会返回一个指向容器中元素类型的指针,而vector<bool>
却是返回一个代理对象。
原因在于,vector<bool>
采用紧凑型存储,即一个bool
只占用一位(bit)。一个8位的字节(byte)可以存放8个bool
,那么返回的指针会指向单个位,而指向单个位(bit)是被禁止的,为了避免这个问题,会用一个代理对象包装,所以会莫名其妙地产生一个新的对象。
解决方法:
- 使用
deque<bool>
,deque
确实存储bool
。 - 使用
bitset
,bitset
使用紧凑表示,无法动态增删。