Effective STL读书笔记
Effective STL 读书笔记
本篇文字用于总结在阅读《Effective STL》时的笔记心得,只记录书上描写的,但自己尚未熟练掌握的知识点,不记录通用、常识类的知识点。
STL按照容器类型,可以分为标准序列容器(deque,vector,list,string),标准关联容器(map,multimap,set,multiset),另外,还有非标准容器,序列类型有slist和rope,关联类型有hash_**类相关容器。标准关联容器总是保持排列顺序。
在关联容器中,确保关联容器对于所使用的比较函数,对于相等的值,总是返回False。
在stl代码中,入参常见缩写,lhs=left hand side,rhs=right hand side。
STL对于数据的处理原则是,进入是拷贝,出来也是拷贝(有些出来是引用,需要根据实际调用函数来决定)
命名空间不要使用全部的空间,比如单个文件中用到vector,可以这样包含
#include <vector>
using std::vector
尽量减少对外部的依赖。
模板形参统一使用typename,而不使用class,因为typename可以用来重定义内部参数类型,而class不行。
C++标准规定,在抛出异常的地方,在退出之前,会调用局部对象的析构函数,确保局部对象析构完成后再退出。
派生类的构造函数、拷贝构造函数、=重载,==重载等函数在实现时,需要显示调用基类对应的函数,调用方法通过类型::函数名的方式来实现,确保派生类相关函数在语义上面的一致性。
vector可以看出是动态增值的数组,它的size为实际存储数据个数,capacity为为存储数据而分配的内存空间。每次扩容,会伴随着内存申请、容器内容拷贝和旧数据的销毁,在VS平台上的vector扩容策略为每次增加当前容量的一般。
vector的优化策略:
对于预存数据数目可预先确定的情况,可以通过预先调用reserve来分配空间,再执行push_back,这种方法比直接push_back效率高
为了减少容器类数据拷贝延迟,可以在容器中存指针
对于判空操作,使用容器自带的empty函数优于使用size函数判空
多余内存空间释放技巧 vector(dest).swap(dest)
vector(dest)创建一个临时变量,它的内容是dest的拷贝,使用vector的拷贝构造函数(它只拷贝真实存放的变量),然后将这个临时变量里面的数据和dest作交换后,dest里面的容量恢复正常状态,临时变量的容量则为dest的容量(通常情况下很大),执行完这句话,临时变量自动析构,释放之前占据的内存,dest则shrink to fit。
map<K,v>里面的元素类型为 pair<const K, V>,这也就说明不要试图去修改map里面的K值。
map[k] = v 的含义是 添加和更新,添加操作=临时变量的默认构造函数+赋值+析构该临时对象,在更新时,效率比insert高
map.insert(v):的含义:仅仅是添加,在添加时,效率比[]高。
remove不是真正意义上的删除,它做不到,它移动区间里面的元素,其中"不用被删除"的元素移动到区间的前部(保持原来相对顺序),它返回一个迭代器,指向"之后不用被删除"的元素之后的元素,一般有erase-remove是惯用法。这其中有例外,list::remove是真正删除元素.
迭代器
输入输出迭代器,这里面的输入输出的视角是以迭代器的视角,左侧站着的是容器,中间是迭代器,右侧的是算法,输入迭代器的意思是:以迭代器为主要视角,往迭代器输入,那么对于左侧的容器来说,就是输出,也就是读取迭代器里面的内容了。
基础迭代器分为输入迭代器(同一位置只读一次)和输出迭代器(同一位置只写一次),在两者功能的基础上,衍生出前向迭代器(同一位置可重复读写,并且支持向前单步移动),在前向迭代器功能基础上,衍生出双向迭代器(支持向后单步移动,也就意味着 支持双向单步移动),在双向迭代器的基础上,衍生出随机迭代器(支持跳跃移动)
算法
使用stl的算法和循环在大多数情况下,比自己手写循环在效率、正确性、可维护性上面都更胜一筹。
使用for_each(a.begin(), a.end(), func);
这里的fun有几种各种不同的情况:
- func为同名本地函数,传入的是函数指针
- func为同名类,传入的是类的"()"操作符的重载函数
- func为类的成员函数,传入的是类的成员函数地址
C和C++的标准库函数遵循传递函数指针是按照传值方式来,形如方式1,在传入函数指针数值,在循环内部根据此指针去寻找确切的函数
函数对象,简单的说,就是对象,这种对象,重载了()运算符,比如 class A,那么可以像调用函数一样使用它,比如A(5),这样使用。函数对象相比于全局函数,它可以保存状态信息,
struct WidgetNameCompare:
public std::binary_function<Widget, Widget, bool>{
bool operator()(const Widget& lhs, const Widget& rhs)const;
}
一般情况下,传递给unary_function(单个入参,返回值类型)或binary_function(两个入参,返回值类型)的非指针类型需要去掉const、引用和入参变量名称。
如果是带指针的入参,则需要如以下来定义:
struct PtrWidgetNameCompare:
public std::binary_functon<const Widget, const Widget, bool>{
bool operator()(const Widget* lhs, const Widge* rhs)const;
}
针对第三种情况,传入判别式为类的成员函数时,根据当前容器类型,如果当前容器里面存储的是类实例时,使用mem_fun_ref包装类成员函数,使其适配for_each的调用格式。当当前存储的是类实例指针时,使用mem_fun来包装.
使用函数对象而不是函数作为STL算法参数,是因为函数指针作为参数会抑制内联优化,而函数对象不会.
算法的名称含义
transform算法:某个函数将被应用到一个区间中的每一个对象,并把调用结果写到某一个地方。
replace_if算法:区间中所有满足判别式条件的对象都将被修改。
partition算法:一个区间中的对象将会被移动,所有满足某个判别式条件的对象会被组织到一起。
在有序序列中,可以使用lower_bound(查找第一次出现4的地方) , upper_bound(查找最后一个出现4的地方的后一个位置),equal_range相当于 lower_bound+upper_bound。
lower_bound(first,last,4)
1-->2-->3 -->4-- >4-->4-->4 -->5- ->6-->7--->8
upper_bound(first,last,4)
stl提供了在有序序列中的二分查找算法 binary_search
在算法调用和手写循环中,关于代码清晰度取决于你要在循环中做什么事情,如果要做的事情和一个算法实现的功能很相近,那么用算法调用会更好。
在软件工程领域中,一份代码被阅读的次数要远远大于它被编写的次数,可读性、可维护性需要特别注意。
Effective STL读书笔记的更多相关文章
- Effective STL 读书笔记
Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...
- effective stl读书笔记 & stl里面提供的算法 & emplace & ostream_iterator
加锁和解锁,也可以在构造函数和析构函数里面,自动调用. 相等和等价的关系:等价是用在排序的时候,跟less函数有关. vector,deque,string 要用erase-remove组合:而关联容 ...
- Effective STL 学习笔记 39 ~ 41
Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value
Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...
- Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据
Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...
- Effective STL 学习笔记 32 ~ 33
Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 31:排序算法
Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 Item 30: 保证目标区间足够大
Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...
- Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor
Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...
随机推荐
- JAVA-JSP内置对象之request范围
相关资料:<21天学通Java Web开发> request范围1.在一次请求内有效.2.如果页面从一个页面跳转到另一个页面,那么属性就失效了.3.如果使用服务器端跳转<jsp:fo ...
- python json (loads(),load(),jump(),jumps())
# loads() str to json data# jumps() json to str# jump() json to filedef ladstest(): data = '{"n ...
- Android Toolbar的使用 顶部标题栏+后退键
最近设计安卓里面有个标题栏,里面有个后退键,可以完成后退之类的功能. 好,刚好可以用Toolbar去实现 上代码:activity_main.xml <?xml version="1. ...
- java小技巧-生成重复的字符
今天碰到个需求,根据字段个数,动态生成sql的占位符,如下: public static void main(String[] args) { System.out.println(String.jo ...
- Android文档 - 账户管理器概述
账户管理器概述 这个类提供了访问到 用户在线账户的集中式注册中心 的能力.用户为每账户输入一次 认证信息(credentials,包含用户名和密码),过过 点击一次(one-click)完成认证的方式 ...
- eclipse配置google代码风格
1.下载google code style的xml文件 地址:https://github.com/google/styleguide 导入xml文件 可能会遇到警告: 版本的问题,忽略即可. < ...
- 《VS2010/MFC编程入门教程》——读书笔记
推荐两个比较好的学习网站:http://v.dxsbb.com/jisuanji/555/ http://www.jizhuomi.com/software/257.html MFC全称Microso ...
- jquery 回车事件实现代码
// 键盘事件 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() keyup事件会在按键释放时触发,也就是你按下键盘起来后的事件 3.keypress() ke ...
- 线段树 + 区间更新: HDU 4893 Wow! Such Sequence!
Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- Java BEAN与EJB的区别
Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean.但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以 ...