Effective STL 中文版记录(一)

Effective STL 章节(一)

——50条有效使用STL的经验(5/50)



第一条、慎重选择容器类型

标准STL序列容器:vector、string、deque和list
标准STL关联容器:set、multiset、map和multimap
非标准的关联容器:hast_set、hash_multiset、hash_map和hash_multimap,存在变体

要注意这些容器可以分为:连续内存容器 和 基于节点的容器

请参考从零开始手写STL,里面会详细介绍各个容器的实现与代码

第二条、不要试图编写独立于容器类型的代码

举例:dequevector都有函数push_back,有的代码员想要构建一个通用的push_back函数来实现多个容器的插入

结论是没必要,因为容器都是特殊的,这样写并不会提高什么效率

可行的方法是:

// 使用typedef来控制
typedef std::vector<Test> TestContainer;
...
TestContainer cw;
Test testone;
cw.push_back(testone);

此时把vector更换为deque一样可以工作

// 使用typedef来控制
typedef std::deque<Test> TestContainer;
...
TestContainer cw;
Test testone;
cw.push_back(testone);

但是依然不建议,最好还是一开始就想清楚用什么容器,不要中途换

第三条、确保容器中的对象拷贝正确而高效

STL的容器在进行插入动作时,一般是先复制对象,再放入容器,所以存进容器的是复制品

参考从零开始手写STL对Vector的实现,在插入时会进行拷贝

这里又会出现什么问题呢?举例:

vector<Father> vw;
class son:
	public Father{...};
	// son 是Father类的派生,除了Father的元素,还额外有自己的元素

son sw;
vw.push_back(sw); // 将son加入到Father的vector中,会导致丢失son独有的元素

这种情况的解决方法是:建议使用指针,即vector<Father *> vw

但是以一个C++程序员的经验来讲,拷贝指针是一件很敏感的事情,实际上如果把模板设置成auto_ptr,编译是不会通过的

所以这条经验的核心思想是:请你注意拷贝的时候,类和类是对应的,别丢东西

第四条、调用empty而不是检查size()是否为0

虽然这两者在代码功能上没有区别,但是在某些特殊情况下,检查size会更慢,而empty总是花费常数时间,所以听吧

第五条、区间成员函数优于与之对应的单元素成员函数

这句话有点长,拆分一下

“区间成员函数”:是一种成员函数,使用两个迭代器参数来确定操作所执行的区间

这么讲可能还是有点迷糊,举例:

int myints[]={10,20,30,40,50,60,70};
std::vector<int> myvector (7);
std::copy ( myints, myints+7, myvector.begin() );

这里的copy就是区间成员函数,它按照给定的迭代器来确定执行区间,类似的有assign、insert、remove等

“单元素成员函数”:每次执行只针对一个元素的函数

实际上就是把上面的代码变成:

int myints[]={10,20,30,40,50,60,70};
int myints[] = {10, 20, 30, 40, 50, 60, 70};
std::vector<int> myvector;
for (size_t i = 0; i < 7; ++i) 
    myvector.push_back(myints[i]);

这里push_back就是单元素成员函数

所以这条经验的意思是:尽量能用一行解决的事情,不要写一个循环去弄

为什么呢?

举例:用insert,既可以进行区间插入,也可以在循环里一次插入一个

// 区间函数
v.insert(v.begin(), data, data + n);

// 单元素函数
for(int i = 0; i < n; i ++)
	v.insert(v.begin() + i, data[i]);

1、很明显加入循环的话,会多调用n-1次insert函数,这个是有可能耗时的
2、对于insert这个函数,每次插入都会使得插入位置后面的元素向后移动,所以用单元素时要额外移动n-1次,明显耗时
3、考虑list这种链表类型的数据,套用循环的插入和删除,会额外增加n-1次指针的赋值,但是压根没必要

所以:能用区间函数就用区间函数,干净、简洁、高效

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值