effective stl(二)

条款十三

vector与string优于动态分配数组

不必使用delete也不必担心delete两次相同的指针

 

 

 

 

条款十四

使用reserve来避免不必要的内存重分配

vector与string的内存扩张

1、分配两倍的空间

2、拷贝(可以的话会移动)原来的元素到新的空间

3、释放原来的空间(拷贝的话需要先析构原来的元素)

 

相关函数

size()个数

capacity()返回最大容量

size() == capacity;时的下一次插入引起内存重新分配

resize(n)将容器变到容纳n个元素的状态,n<size裁剪,n>size填充(默认构造或给定值),n>capacity()重新分配内存。

reserve(n)重配内存,n小于当前容量时vector忽略操作,string调整到size与n的较大者;大于时可能重配(如果可以)。

 

 

 

 

 

条款十五

string实现

(1)

包含:

size即字符个数

capacity即容量

value即实际的字串

可能包含:

分配子的拷贝

引用计数

 

A类型:

无alloc优化

4倍与指针,1次动态分配

结构:

allocator

size

capacity

value pointer -> refcount(引用计数) + 实际字串

 

B类型

等于指针,两次动态分配

结构:

指针                 ->                          size

(可能alloc)                                capacity

                                                      refcount

                                                      pointer         ->            实际字串

                                                      同步控制(6倍于指针大小)

size + capacity + refcount + pointer = 4倍于指针的大小

 

C类型

等于指针,一次动态分配

pointer ->  size 

                 capacity

                 refcount

                 x(共享性相关的数据)

                 value

即C类型不支持自定义allocator,所有string使用同一个分配子

 

D类型

7倍于一个普通指针,小于15时不需要动态分配(即小字符串优化)

allocator

pointer -> value

足够容纳15字符的空间

size

capacity

 

无需多线程控制,因为并没有引用计数

 

共享性D < A < B与C

 

 

(2)

将vector与string传给旧的API

&vector[0]

&(*vector.begin())

string.c_str();

对于string,C API不能对其进行改变

对于vector则为不能改变元素数量,因为vector本身无法察觉这些变化(start last finish三个指针并不会跟着传递到API里)

若要在API内修改:

vector:

使用resize( fun(&vector[0],size ) 让fun返回新size来使得vector进行改变。

string:因为vector与string可以相互用来初始化,所以先把string传到vector里,然后再按照vector的方法改变vector,然后再用改变号的vector去初始化原来的string。

 

 

 

 

条款十七

使用swap除去多余的容量

vector   (orginal).swap(orginal);

使用orginal作为副本创建一个无名的临时vector对象,这个对象的容量等于prginal,然后把这个对象和orginal进行交换达到除去orginal中多余容量的作用。(其实做到的是当前实现下的最小,即减小到用拷贝构造函数构建的容器的大小)

 

 

 

 

 

条款十八

避免使用vector<bool>

vector<bool>的[]返回的是一个代理对象,用以模拟bool的行为,即不是真正的bool类型。

只有type *p = &vector<type>[0]成立才是容器,也就是说vector<bool>不算是真正的容器

deque可以代替,或者bitset

 

 

 

 

 

条款十九

理解等价与相等的不同

非成员函数:

find基于 operator== 即相等,成员版本的find则基于等价,即operator<(!(a<b) && !(b<a)成立即等价)

insert基于operator<,即等价

 

关联容器的等价检测

a,b

return !(a<b)

           &&

           !(b<a);

用户定义的类型比较

return !key_compare()(a,b)

          &&

          !key_compare()(b,a);

key_compare()返回用户定义的函数对象(或用以比较的函数对象)

 

set<type,comp>

comp要转为可调用对象

 

 

 

 

 

条款二十

为包含指针的关联容器指定比较类型

因为关联容器在未指定时是会使用指针内的地址值作为比较准则的,智能指针与迭代器同理,要根据它们指向的值来排序的话需要自己传入比较子。

 

 

 

 

 

条款二十一

总是让比较函数在相等是返回false

否则关联容器会把两个相等的值判断为不等价(根据之前的比较规则),那么当你用范围取出函数的时候就不能得到这两个等价的结果了。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值