读 "Effective STL" 笔记

 

C2@vector & string

 

reserve()与resize()的区别在于:reserve()仅仅会为你分配一段未经初始化的内存空间,容器内元素的个数也即容器的size()并不会改变,使用reserve()的初衷在于当容器的使用情况可预知时,提前调用reserve()预分配空间可避免reallocation所带来的沉重开销;resize()的行为是分配一段已初始化的空间,容器内元素的个数(Container.size()以及Container.end())随之改变,resize()的初衷在于一些基于assignment的STL算法只能对已经初始化完成的(也即constructor()已被调用的)内存空间施加操作。

 

std::string包含的成员可能会包括,

@size & @capacity;

@pointer & @allocator: 字符串的实际分配是经由Allocator通过动态分配实现的,allocator会作为具象实例存在于每个string中;

@reference count: 从节省空间的角度考虑,很多的库都会含有该成员。当需要使用某字符串例如”hello cplusplus”时,程序会动态分配一份,接下来所有使用该字符串的string仅仅通过@pointer指向该字符串,其被引用的个数记录在@reference count中,@reference count减为0时动态进行销毁。

基于这些成员可以得知,为什么sizeof(string)会出人意料的大。




C3@Associative Container

 

在STL中有两种“相等”:一种是algorithm::find()所定义的相等,基于operator==()实现;另一种则是std::set/map所定义的相等,基于operator<()实现。二者都用于查找,直观来看operator==()足够使用,而之所以operator<()会被使用在于set/map是有序的,从有序的容器中查找元素,基于operator<()的二分法能够提供远优于线性查找的性能。

 

当然,利用operator<()定义的“相等”可能会让人觉得过于繁琐 A == B <--> !operator<(A, B)&& !operator<(B, A),翻译一下就是A不小于B同时B不小于A。熟悉二分法的朋友或许会问,何不将operator==()与operator<()混在一起使用,毕竟二分法中是先判断”if(B == mid)”,当不等时才会引入”<”。问题在于这就需要operator==()和operator<()的定义保持一致性,考虑一个字符串的比较,如果operator==()假定大小写不敏感而operator<()假定大小写敏感,这个查找就会出现问题。换句话来讲,混合使用可能会引入定义的不一致进而导致程序出现问题。

 

最后,当容器中存储的是你声明的Class时,记得定义自己的operator==(), operator<()。

 

 

C4@Iterator

 

鉴于很多container的成员函数要求输入参数是iterator而将const_iterator拒之门外,所以在很多情况下const_iterator的使用者就必要为手里的const_iterator摘掉const的帽子。卸帽工具?第一反馈该是const_cast<>,不过让人略感意外的是…这直观的方式在多数情况下(string, vector除外)会难以通过编译。

 

问题的原因在于对大多数container(包括list, deque, set,multiset, map, multimap)而言,它们的iterator和const_iterator实现源于不同的类,通过const_cast<>完成不同class的转化,Bjarne的口味应该不会这么重。Scott给出的解决方案是引入advance()和distance():

std::advance ( iter ascontainer.begin(), 

                           std::distance<const_type>( container.begin(), const_target_iter )

 

至于前文提到的例外-- string和vector,const_cast<>是可以起作用的,原因在于这两个容器里pointer和iterator是等价的,即为

vector<T>::iterator等价于T*, 同时vector<T>::const_iterator等价于const T*。自然const_cast<>刚好够用。

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值