###学习《C++ Primer》- 2
点击查看Evernote原文。
#@author: gr
#@date: 2014-10-01
#@email: forgerui@gmail.com
Part 2: STL顺序容器(第9章)
一、标准库array(C++11)
array的大小固定,不能省去,它是容器的一部分。
//保存42个int, 初始1,2,其余40个元素初始为0
array<int, 42> = {1, 2}
//保存24个string
array<string, 24>
array<int, 10>::size_type i; //正确
array<int>::size_type j; //错误,没有大小
//类的话必须有一个默认构造函数
array<Widget, 10> aw;
内置数组不能进行数组赋值,拷贝,array
可以。
int digs[10] = {1, 2, 3};
int cpy[10] = digs; //错误,不支持赋值
array<int, 10> dig = {1, 2, 3};
array<int, 10> cp = dig; //正确,可以进行赋值,数组大小要一致
二、容器的关系运算符
只有当元素定义了相应的比较运算符,才可以使用容器的关系运算符。
vector<int> v1 = {1, 3, 7}; //初始列,C++11
vector<int> v2 = {1, 3, 7, 9};
v1 < v2 //true,所有元素相等,v1数目更少
三、STL容器使用的是拷贝
用一个对象初始化容器,是将该对象的拷贝放进容器中的,容器中的元素修改与原来的对象没有任何影响。
四、使用emplace_back
,emplace
,emplace_front
emplace
可以直接在内存中创建对象,并且效率更高。
vector<Sales_data> c;
//直接在空间创建对象,节省开销
c.emplace_back("123", 25, 25.99);
//编译错误,没有3个参数的构造
c.push_back("123", 25, 25.99);
//构造临时对象,拷贝进入容器,销毁对象
c.push_back(Sales_data("123", 25, 25.99));
五、容器的访问成员函数
可以使用front
,back
进行直接访问,也可以通过迭代器进行解引用,获取元素,但在进行访问之前,最好要检测容器是否为空,如果为空,将会产生不确定行为。
对提供了随机访问的容器可以使用下标访问(如v[0]
),list
则不存在下标访问。下标访问返回的是元素的引用,对其赋值可以直接修改容器中元素的值。下标运算不检查是否在合法范围内,下标越界是一种严重的错误,会导致runtime error
。也可以使用at
成员函数,如果下标越界,at
会抛出一个out_of_range
异常。
vector<string> sv; //空vector
cout << sv[0]; //运行时错误
cout << sv.at(0); //抛出一个out_of_range
六、容器的删除操作
forward_list
没有pop_back
函数,vector
和string
没有pop_front
操作。erase(p);
删除迭代器p所指定的元素,erase(p, q);
删除迭代器p到q范围的元素。在删除之前,必须保证元素是存在的。
forward_list
的删除需要两个迭代器,一个是正在处理元素的,一个是前驱元素的迭代器。
//删除容器中的奇数
forward_list<int> flst = {0, 1, 2, 3, 4, 5, 6, 7};
auto prev = flst.before_begin(); //表示flst的“首前元素”
auto curr = flst.begin();
while (curr != flst.end()) {
if (*curr % 2){ //元素为奇数
curr = flst.erase_after(prev); //删除它并移动curr
}else{
prev = curr;
curr++;
}
}
七、改变容器的大小
使用resize
来改变容器的大小,array
不支持resize
。如果当前大小大于所要求的大小,容器后部的元素会被删除;如果当前大小小于要求的大小,将新元素加入到容器中。
list<int> il(10, 42);
il.resize(15); //在最后加入5个0
il.resize(25, -1); //在最后加入10个-1
il.resize(5); //删除末尾的20个元素
八、在循环中保持迭代器
容器的操作可能会使已有的迭代器失效,如何在循环过程中保持这些迭代器,以使整个循环过程正确?
办法是使用成员函数操作的返回值更新迭代器,虽然list
的某些操作并不影响迭代器,但为了统一,最好所有的顺序容器都使用相同的形式。
vector<int> vi = {1, 2, 3, 4, 5};
auto iter = vi.begin();
iter = vi.insert(iter, 2); //用insert返回值更新迭代器
iter = vi.erase(iter); //删除元素
九、不要试图保存end返回的迭代器
容器的操作会改变end()
返回的迭代器,所以不要保存它。这也是为什么在循环中,为何反复调用v.end()
进行判断是否结束。
it = v.begin();
while (it != v.end()){ //反复调用v.end()检查
//...
}
十、理解vector
是如何增长的
capacity
表示容量,是已经申请的内存空间,size
是已经保存的元素的数目。
使用reserve
改变容器的容量,resize
改变容器的大小。
当vector
内存不够用的时候,会把整个vector
复制到更大的内存空间中,造成开销变大。
使用reserve
事先申请大的空间,可以避免vector
的拷贝,但如果容量过大,则会浪费。
在《Effective STL》中的Topic17里面讲解使用"swap技巧"去除多余的容量,实际上,C++11中提供了shrink_to_fit
函数来退回不需要的内存空间。
十一、string
独有的一些操作
使用string
进行字符串处理,可以极大地简化我们的工作。
一般程序设计语言,都会提供
substr
函数进行字符串截取。//pos开始位置,n截取的个数
s.substr(pos, n);
insert
,erase
基于下标版本
string
提供了基于下标版本的成员函数。s.insert(s.size(), 5, '!'); //在最后插入5个!
s.erase(s.size()-5, 5); //删除最后5个元素
append
,replace
string s("C++ Primer"), s2 = s;
s.insert(s.size(), " 4th Ed."); //追加
s.append(" 4th Ed."); //等价上面insert方法
replace
是erase
和insert
操作的简写:
s.erase(11, 3);
s.insert(11, "5th");
s2.replace(11, 3, "5th"); //等价于上面两句
s2.replace(11, 3, "Fifth"); //删除3个字符,添加5个也是可以的搜索操作
string
一共有6种搜索操作,分别是find
,rfind
,find_first_of
,find_first_not_of
,find_last
,find_last_not_of
。这些都是大小写敏感,返回第一个匹配出现的位置。string name("AnnaBelle");
name.find("Anna"); //返回0
//使用find_first_of查找在list_c字符出现的第一个位置
string list_c("cnl");
name.find_first_of(list_c); //返回1,即n第一次出现的地方
数值转换
int i = 42;
string s = to_string(i); //将i转换为字符表示形式
double d = stod(s); //将string转换为浮点数
十二、容器适配器
适配器是一种机器,接受一种已有的容器类型,对其改造,使其行为看起来像一种不同的类型。我们定义了适配器,就只能使用适配器提供的操作,不能使用底层容器的操作。
stack
栈适配器可以使用vector
,deque
,list
实现;queue
可以使用deque
,list
实现,因为vector
没有pop_front
;
###学习《C++ Primer》- 2的更多相关文章
- 学习C++ Primer 的个人理解(一)
<C++ Primer>这本书可以说是公认的学习C++最好的书,但我觉得不是特别适合作为教材,书中内容的顺序让人有些蛋疼.我个人认为初学此书是不能跳着看的.如果急于上手的话,我更推荐< ...
- 学习C++ Primer 的个人理解(九)
这一章介绍顺序容器,在之前的第三章中,了解到的vector就属于顺序容器的一种. 一个容器就是一些特定类型对象的集合. 除了vector,还有哪些顺序容器? vector: 大小可变,随机访问的速度很 ...
- 学习C++ Primer 的个人理解(三)
第三章,主要内容是字符串和数组.感觉作者的意图是希望读者可以早一点可以写出简单的小程序,并且可以早点接触迭代器这种思想. 在我看来,这种内容的难度并不大. 对于编程来说,最重要的应该是思想,类似vec ...
- 学习C++ Primer 的个人理解(二)
本身就一定基础的读者我想变量常量这些概念应该已经不是问题了.但是本章还是有几个重点,需要特别留意一下的: 1.初始化和赋值是不同的操作 2.任何非0值都是true 3.使用新标准列表初始化,在有丢失精 ...
- 学习C++.Primer.Plus 11 使用类
1.操作符重载 重载操作符的几个限制: a) 重载的至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载操作符. b) 不能违反操作符原有来的句法规则. c) ...
- 学习C++.Primer.Plus 10 对象和类
1.类的声明和定义 类的声明和定义. 类声明的格式如下: class className { private://private 是类对象的默认访问控制,因此,可以省略 data member del ...
- 学习C++.Primer.Plus 8 函数探幽
1. 内联函数 普通函数调用: 存储调用指令的地址->将函数参数复制到堆栈->跳到函数地址执行代码(返回值放到寄存器)->跳回调用指令处 2. 当代码执行时间很短,且会被大量调用的 ...
- 学习C++.Primer.Plus 7 函数
C++的返回值类型不能是数组 函数原型中的变量名相当于点位符,因此不要求提供变量名. void cheers(int); C++中不指定参数列表时就使用活力号: void saybye(...); 通 ...
- 学习C++.Primer.Plus 6 分支语句和逻辑操作符
||. &&操作符是一个顺序点 < 操作符从左向右结合 ; < age < )//17<age为true, = 1,肯定 < 27.所以为整个条件为tru ...
- 学习C++.Primer.Plus 5 循环和关系表达式
C++将赋值表达式的值定义为左侧成员的值 赋值操作符是自右向左结合的 cout.setf(ios:: boolalpha);//调用设置标记,命令cout输出true或false,而非1或0. 任何表 ...
随机推荐
- 函数 stat() 详解
先看看MSDN的解釋: stat(): Get status information on a file. Parameters: path: pointer to a string con ...
- MSSQLSERVER数据库- 数据类型Timestamp
Timestamp:亦称时间戳数据类型,它提供数据库范围内的惟一值,反应数据库中数据修改的相对顺序,相当于一个单调上升的计数器.当它所定义的列在更新或者插入数据行时,此列的值会被自动更新,一个计数值将 ...
- JavaScript要点 (六) 函数参数
JavaScript 函数对参数的值没有进行任何的检查. 函数显式参数(Parameters)与隐式参数(Arguments) 函数的显式参数: functionName(parameter1, pa ...
- Windows 7 EXE图标丢失修复方法
有过Win7下的一些EXE文件图标莫名奇妙丢失,但功能却正常的情况吗?这是图标缓存的问题,应该是Win7的bug. 在命令提示符下输入下列命令即可恢复. 以下是代码片段: taskkill /im e ...
- 用CSS让网页背景图片居中的方法
网页背景居中的方法有很多种的.这里介绍一些用CSS让背景图片居中的方法. 让背景图片居中的第一个方法是用像素设定,很多都用这种,但是也是最麻烦的: <div style="width: ...
- 飘逸的python - 理解打开文件的模式
当我们用open()函数去打开文件的时候,有好几种打开的模式. 'r'->只读 'w'->只写,文件已存在则清空,不存在则创建. 'a'->追加,写到文件末尾 'b'->二 ...
- vmware安装 ios10.8 过程
前言:由于mac笔记本太贵,并且对于用thinkpad 习惯的我,实在是不想买mac,没办法,只能在win7下面使用vmware 安装mac虚拟机了.但是ios的版本一直变,vmware也一直在升级, ...
- QSqlQueryModel的实例操作
QSqlQueryModel类为SQL的结果集提供了一个只读的数据模型,下面我们先利用这个类进行一个最简单的操作. 我们新建Qt4 Gui Application工程,我这里工程名为queryMode ...
- PHP之open_ssl
http://www.wapm.cn/phpdoc/zh/openssl.installation.html http://liuxufei.com/weblog/jishu/376.html dem ...
- Apache的rewrite规则详细介绍
Apache的rewrite规则详细介绍 发布日期:2008-09-02 16:16 来源: 作者: 点击:7044 rewrite标志 R[=code](force redirect) 强制外部重定 ...