Effective STL 50条有效使用STL的经验(个人笔记)

Effective STL 50条有效使用STL的经验

容器
条款01:慎重选择容器类型
容器分类。1)序列容器(vector、string、deque和list)和关联容器(set、map、multiset、multimap)。2)或连续内存容器和基于节点的容器。
连续内存容器:vector、string、deque和非标准的rope。
基于节点的容器:list和forward_list(c++11)、所有标准的关联容器(set、map、multiset、multimap实现方式是平衡树),非标准的哈希容器(unorder_set、unorder_map c++11)。
基于节点的容器(除deque)的插入和删除操作从来不会使迭代器、指针和引用变为无效(除非它们指向一个你正在删除的元素)。而针对连续内存容器的插入和删除操作一般会使指向该容器的迭代器、指针和引用变为无效(删除点及之后的所有迭代器失效,添加可能导致重新分配内存,导致所有迭代器失效)。
当插入操作仅在容器末尾发生时,deque的迭代器可能会变为无效,但指针和引用有效。Deque是唯一的、迭代器可能会变为无效而指针和引用不会变成无效的STL标准容器。
条款02:不要试图编写独立于容器类型的代码
只有序列容器才支持push_back或push_front。
当你向序列容器中插入对象时,对象位于被插入的位置处;当你向关联容器中插入对象时,容器会按照其排序规则,将该对象移动到适当的位置上。
要求随机访问迭代器的操作:sort、stable_sort、partial_sort和nth_element。
Vector<bool>并不总是表现的像一个vector,它实际上并没有存储bool类型的对象。
在某些情况下,你意思到自己选择的容器类型不是最佳,你想使用令一种容器类型。在写容器代码之前,你需要考虑使用封装技术。
最简单的方式是通过对容器类型和其迭代器类型使用类型定义(typedef),词法层面。要想减少在替换容器类型时所需要修改的代码,你可以把容器隐藏到类中。
条款03:确保容器中的对象拷贝正确而高效
当(通过如insert或push_back之类的操作)向容器中加入对象时,存入容器的是你所指定的对象的拷贝。
Widget w[n];创建了n个widget的数组,每个数组都使用默认构造函数来创建。
条款04:调用empty而不是检查size是否为0
你应该使用empty形式,理由:empty对所有的标准容器都是O(1),而对一些list实现,size为o(n)。
List的 size()和splice():有一个为O(n)和另一个为O(1)。
条款05:区间成员函数优先于与之对应的单元素成员函数
容器赋值成员函数:assign。对于所有的标准序列容器(vector、string、deque和list),它都存在。
通过利用插入迭代器的方式来限定目标区间的copy调用,几乎都应该被替换为对区间成员函数的调用。
对于标准序列容器,使用区间成员函数有更高的效率(函数调用、元素移动、内存分配、多次赋值等方面);对于关联容器,使用区间成员函数效率不会更低。但是,区间成员函数,代码更加易懂,可维护性强。
区间成员函数:
区间创建:container::container(InputIterator begin,InputIterator end)
区间插入:
Void container::insert(iterator position, InputIterator begin,InputIterator end) 标准序列容器需要提供插入位置
Void container::insert(InputIterator begin,InputIterator end)关联容器利用比较函数来决定元素该插入何处
区间删除:
iterator container::erase(iterator begin, iterator end)
void container::erase(iterator begin, iterator end)
区间赋值:Void container::assign(InputIterator begin,InputIterator end)
选择区间成员函数理由:1)写起来容易;2)更能清晰地表达你的意图;3)它们表现出了更高的效率。
条款06:当心C++编译器最烦人的分析机制
在函数形参中,参数int(d)两边的括号是多余的,参数int d()后边的括号使d理解为(隐式)函数指针,与int (*d)()等价。
读取文件:
Ifstream datafile(“ints.dat”);
Istream_iterator<int> dataBegin(datafile);
Istream_iterator<int> dataEnd;
List<int> data(dataBegin,dataEnd);
条款07:如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete
指针容器在自己被析构时会析构所含的每个元素,但指针的“析构函数”不做任何事情,当然不会调用delete,直接导致资源泄露。
为了防止资源泄露,可以把使用智能指针(std::shared_ptr)或手工删除(也可以借助for_each和DeleteObject()函数对象)
条款08:切勿创建包含auto_ptr的容器对象
auto_ptr意味着所有权的转移。当你复制一个auto_ptr时,它所指向的对象的所有权被移交到复制的auto_ptr上,而它自身被置为NULL。
包含auto_ptr的容器对象应该被禁止。例如当对该对象sort时,就会发生意想不到的情况。
条款09:慎重选择删除元素的方法
序列容器vector、stri
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值