Effective STL(二)

1、使用reserve来避免不必要的重新分配

对于vector和string来讲,存储数据量大于当前分配的空间时,会进行动态增加空间

(1)分配新的内存块,新的内存块是目前容量的好几倍,vector和string的容量每次一2位因数增长

(2)把所有元素从旧的内存拷贝到新的内存中

(3)销毁旧内存中的对象

(4)回收旧内存

使用reserve提前开辟一个你需要的足够大小的内存空间,这样可以避免真分配的开销和迭代器、指针、引用失效以及拷贝带来的效率损耗

2、交换内存(将容器的容量收缩到合适的大小)

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

表达式建立了一个临时vector,他是contestants的一份拷贝,vector的拷贝构造函数做了这个工作,但是vector的拷贝构造函数只分配拷贝的元素需要的内存,所以这个临时vector没有多余的容量,然后在交换数据,这是就完成了,当结束时,临时容器就有了会进行释放销毁,

同样 string也可以这样做

string(s).swap(s)

代码举例:

    vector<int> v;
    for(int i = 0; i < 100000; i++)
    {
        v.push_back(i);
    }//此时v的size为100000,但是实际容量大于100000
    vector<int> (v).swap(v);

清空容器并且最小化它的容量,写法如下

vector<int>().swap(v);

string也是一样:

string().swap(v)

3、避免使用vector<bool>

(1)、他不是容器

vector<bool>是一个伪容器,并不保存真正的bool,而是对bool进行了打包保存,vector中保存的每一个bool占用一个单独的比特,而一个8比特的字节将容纳8个bool,在内部,vector<bool>使用了与位域等价的思想,所以你可以创建一个指针指向真正的bool,但是禁止有单个指向比特的指针

所以作为容器,它不支持

vector<bool> v

bool*p = &v[0]//这种写法编译都过不去

(2)、他并不容纳bool

需要容纳bool类型的容器,可以选中deque,deque内部保存的是真正的bool值

4、相等和等价的区别

相等的概念是“==”,如果“x==y”返回true

等价是基于在一个有序区间中的对象值的相对位置,等价一般在每种关联容器(set、map、multiset,multimap)中排序方面有意义,所以排序时,“<”,需要同时满足,a<b为真,同时a>b为假。

5、永远让比较函数对相等的值,返回false

关联容器中的set,如果插入了一个数据10a,再插入一个10b,同时我们指定set的比较函数为less_equal,less_equal的含义是小于等于,set是关联容器,要判断是否数据是否等价所以判断!(10 a< 10b)&&!(10a <= 10b)来判断是否等价,这样就会出现结果false&&false,也就是说得出了一个结论,10b与容器中的数据不等价,这样就把数据保存进去了,但这样做违反了set容器的初衷,他需要保存不重复的数据,这样做算是破坏了容器,为了避免这种陷阱,需要比较函数的返回值表明在此函数的排序方式下,一个值是否大于另一个,相等的值,绝不应该大于另一个,所以比较函数总应该对相等的值返回false

6、不要原地修改set和multiset的键

所有的标准关联容器中,set和multiset保持他们的元素有序,对于map和multimap来说,特别简单,因为视图改变这些容器的一个键值的程序将不能被编译

因为map中的键的类型是const修饰的,不能被修改,简单吧

如果想要安全的改变set、multiset、map、multimap中的元素:

(1)定位你想要改变的内容元素

(2)拷贝一份要被修改的元素,

(3)修改副本

(4)从容器里删除元素,调用erase

(5)把新值插入容器

7、关注效率时在map::operator[]和map-insert之间选择

map[1] = 1.5,相信大家都了解过这种初始化方式,但是这种实际上等于,先默认构造一个对象,然后立即个它赋值,使用insert将新增的对象放到map中,在修改他的value所以这种方法极可能降低性能,语句很简单,但实际上执行的代码很多

用值构造比默认构造之后在进行赋值显然更高效,所以直接使用insert函数来替换operator[]的使用 m.insert(std::make_pair(2,2));

更新一个元素的时候,operator[]方式比insert要高效(同学可以自己了解一下)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值