《C++ Primer》学习笔记【第二部分 C++标准库】
第8章 IO库
IO对象不能复制,即1.IO对象不能存储在vector或其他容器中 2.如果需要传递或返回IO对象,必须传递或返回指向该对象的指针或引用。
一般情况下,如果要传递IO对象以便对它进行读写,用非const引用的方式传递这个流对象。(因为要对IO对象进行读写)
条件状态:IO标准库管理一系列条件状态成员,用来标记给定的IO对象是否处于可用状态,或碰到了哪种特定的错误。流的状态由bad、fail、eof和good操作揭示;clear和setstate操作用于改变条件成员的状态。
输出缓冲区的管理:以下几种情况将导致缓冲区的内容被刷新。
1.程序正常结束时,清空所有输出缓冲区。
2.在一些不确定的时候,缓冲区可能已经满了,缓冲区会在下一个值之前刷新。
3.用操作符显示刷新缓冲区,如endl。
4.每次输出操作执行完后,用unitbuf操纵符设置流的内部状态,清空缓冲区。
5.将输出流和输入流关联(用tie函数)起来。在此情况下,在读输入流时刷新其关联的输出缓冲区。标准库将cin和cout绑在一起。
(如果程序崩溃,则不会刷新缓冲区,最好的方法是保证所有的输出操作都显式地调用了flush或endl; 交互式系统通常应确保它们的输入和输出流是绑在一起的)
文件的输入与输出:
如果要把fstream对象与另一个不同的文件关联,则必须先close现在的文件,再open另一个文件。
考虑如何使用循环语句打开一些文件?
//files是一个vector对象,包含一些要打开并读取的文件名
//每次循环构造一个名为input的ifstream的对象
while(it != files.end()){
ifstream input(it->c_str());
if(!input) break;
while(input >> s) process(s);
++it;
}
//也可将input定义移到while外,那么需要更仔细地管理流对象。
//每次需要打开新文件,故要关闭当前的文件流
//关闭流不能改变流的内部状态,如果读写操作失败,状态将保持为错误模式,故需要调用clear
ifstream input;
vector<string>::const_iterator it = files.begin();
while(it != files.end()){
input.open(it->c_str());
if(!input) break;
while(input >> s) process(s);
input.close();
input.clear();
++it;
}
文件模式:....(此坑待填)
字符串流:
//1.如何每次读入一行,并分别处理每行中的每个单词
string line, word;
while(getline(cin, line)){
istringstream stream(line);
while(stream >> word){
// do sth
}
}
//2.stringstream提供的转换和/或格式化
//一般情况下,使用输入操作符读取string时,空白符会忽略。
int val1 = , val2 = ;
ostringstream format_message;
format_message << "val1: " << val1 << "\n"
<< "val2: " << val2 << "\n";
istringstream input_istring(format_message.str());
string dump;
input_istring >> dump >> val1 >> dump >> val2;
cout << val1 << " " << val2 << endl;
第9章 顺序容器
赋值和swap:
赋值相关运算会导致指向左边容器内部的迭代器、引用和指针失效,而swap操作将容器内容交换,迭代器、引用和指针不会失效。(array和string除外)
除array外,swap不对任何元素进行拷贝、删除或插入操作,因此可以保证常数时间内完成。
swap两个array会真正交换他们的元素,但指针、引用和迭代器所绑定的元素保存不变。
网摘string的swap
template<class _Elem,
class _Traits,
class _Alloc> inline
void __CLRCALL_OR_CDECL swap(basic_string<_Elem, _Traits, _Alloc>& _Left,
basic_string<_Elem, _Traits, _Alloc>& _Right)
{ // swap _Left and _Right strings
_Left.swap(_Right);
}
void __CLR_OR_THIS_CALL swap(_Myt& _Right)
{ // exchange contents with _Right
if (this == &_Right)
; // same object, do nothing
else if (_Mybase::_Alval == _Right._Alval)
{ // same allocator, swap control information
#if _HAS_ITERATOR_DEBUGGING
this->_Swap_all(_Right);
#endif /* _HAS_ITERATOR_DEBUGGING */
_Bxty _Tbx = _Bx;
_Bx = _Right._Bx, _Right._Bx = _Tbx;
size_type _Tlen = _Mysize;
_Mysize = _Right._Mysize, _Right._Mysize = _Tlen;
size_type _Tres = _Myres;
_Myres = _Right._Myres, _Right._Myres = _Tres;
}
else
{ // different allocator, do multiple assigns
_Myt _Tmp = *this;
*this = _Right;
_Right = _Tmp;
}
}
网摘vector的swap
template<class _Ty,
class _Alloc> inline
void swap(vector<_Ty, _Alloc>& _Left, vector<_Ty, _Alloc>& _Right)
{ // swap _Left and _Right vectors
_Left.swap(_Right);
}
void swap(_Myt& _Right)
{ // exchange contents with _Right
if (this == &_Right)
; // same object, do nothing
else if (this->_Alval == _Right._Alval)
{ // same allocator, swap control information
#if _HAS_ITERATOR_DEBUGGING
this->_Swap_all(_Right);
#endif /* _HAS_ITERATOR_DEBUGGING */
this->_Swap_aux(_Right);
_STD swap(_Myfirst, _Right._Myfirst);
_STD swap(_Mylast, _Right._Mylast);
_STD swap(_Myend, _Right._Myend);
}
else
{ // different allocator, do multiple assigns
this->_Swap_aux(_Right);
_Myt _Ts = *this;
*this = _Right;
_Right = _Ts;
}
}
访问元素: 访问成员函数和下标操作返回的都是引用,如果容器是const容器,则返回const引用。
迭代器失效:
对于vector和string,存储空间被重新分配则迭代器、引用和指针失效。
对于deque,插入删除首尾位置外的任何位置则迭代器、引用和指针失效,在首尾位置添加元素,迭代器会失效,但指向已存在的元素的引用和指针不会失效。
对于list和forward_list,迭代器、引用和指针仍有效。
第10章 泛型算法
再探迭代器:
插入迭代器,back_inserter, front_inserter, inserter, it是插入迭代器,属于迭代器适配器,it = t在it指定位置插入t并自动调整it指向的位置。
int main(){
vector<int> ve;
deque<int> de;
auto it = back_inserter(ve);
auto it2 = front_inserter(de);
for(int i = ; i < ; i++)
it = i, it2 = i; for(auto& e: ve)
cout << e << ' ';
cout << endl; for(auto& e: de)
cout << e << ' ';
cout << endl; auto it3 = inserter(ve, --ve.end());
for(int i = ; i < ; i+=)
it3 = i;
for(auto& e: ve)
cout << e << ' ';
cout << endl;
return ;
}
/*
0 1 2 3 4
4 3 2 1 0
0 1 2 3 100 200 300 400 4
*/
第11章 关联容器
正常情况下,解引用一个迭代器所返回的类型和下标运算符返回的类型是一样的,map除外。map解引用返回value_type对象,即pair型,下标返回mapped_type对象,即值型。
无序容器:不是基于比较符,而是通过哈希函数映射到桶。无序容器在存储上组织为一组桶,每个桶保存0个或多个元素。我们需要提供函数来替代==运算符和哈希计算函数。
第12章 动态内存
动态内存:
int *p = new (nothrow) int; //如果分配失败,new返回空指针
int *p0 = new int;//如果分配失败,new抛出std::bad_alloc
int *p1 = new int();
int *p2 = new int[10]();
new分配一个数组时,得到的是数组元素类型的指针,而不是数组类型。因此不能对动态数组调用begin或end, 这些函数使用数组维度来返回首元素和尾后元素的指针,也不能用范围for语句。
new可以分配一个大小为0的数组,返回合法非空指针,保证与new返回的其他任何指针都不同。
释放动态数组不加[]和释放单一对象加[]都是未定义的。
malloc与new有什么区别?
前者是函数,不含构造函数,返回void。后者是运算符,含构造函数,返回类型。
智能指针:此坑待填
allocator类:
new将内存分配和对象构造组合在一起,delete将对象析构和内存释放组合在一起。
分配单个对象时通常希望将内存分配和对象初始化组合在一起;当分配一大块内存时,内存分配和对象初始化组合在一起往往会导致不必要的浪费。
allocator使得内存分配和对象构造分离开来。allocator分配的内存是未构造的。
allocator<T> a //定义一个allocator对象,可以分配T类型
a.allocate(n) //分配n个未构造的T类型的内存
a.deallocate(p, n) //释放n个从p开始的内存,p必须是由allocate返回的指针,n必须是创建时的大小,调用前必须先对每个对象调用destroy
a.construct(p, args) //在p指向的内存中构造对象
a.destroy(p) //析构p指向的对象
使用未构造的内存,行为是未定义的。
当然,一个一个构造会很麻烦,标准库还为allocator类定义了两个伴随算法,拷贝和填充未初始化内存的算法。
《C++ Primer》学习笔记【第二部分 C++标准库】的更多相关文章
- Python学习笔记011_模块_标准库_第三方库的安装
容器 -> 数据的封装 函数 -> 语句的封装 类 -> 方法和属性的封装 模块 -> 模块就是程序 , 保存每个.py文件 # 创建了一个hello.py的文件,它的内容如下 ...
- C++ Primer学习笔记(二)
题外话:一工作起来就没有大段的时间学习了,如何充分利用碎片时间是个好问题. 接 C++ Primer学习笔记(一) 27.与 vector 类型相比,数组的显著缺陷在于:数组的长度是固定的,无法 ...
- C++ Primer学习笔记(三) C++中函数是一种类型!!!
C++中函数是一种类型!C++中函数是一种类型!C++中函数是一种类型! 函数名就是变量!函数名就是变量!函数名就是变量! (---20160618最新消息,函数名不是变量名...囧) (---201 ...
- 《DOM Scripting》学习笔记-——第二章 js语法
<Dom Scripting>学习笔记 第二章 Javascript语法 本章内容: 1.语句. 2.变量和数组. 3.运算符. 4.条件语句和循环语句. 5.函数和对象. 语句(stat ...
- The Road to learn React书籍学习笔记(第二章)
The Road to learn React书籍学习笔记(第二章) 组件的内部状态 组件的内部状态也称为局部状态,允许保存.修改和删除在组件内部的属性,使用ES6类组件可以在构造函数中初始化组件的状 ...
- [HeadFrist-HTMLCSS学习笔记]第二章深入了解超文本:认识HTML中的“HT”
[HeadFrist-HTMLCSS学习笔记]第二章深入了解超文本:认识HTML中的"HT" 敲黑板!!! 创建HTML超链接 <a>链接文本(此处会有下划线,可以单击 ...
- STL笔记(6)标准库:标准库中的排序算法
STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew A ...
- ArcGIS案例学习笔记_3_2_CAD数据导入建库
ArcGIS案例学习笔记_3_2_CAD数据导入建库 计划时间:第3天下午 内容:CAD数据导入,建库和管理 目的:生成地块多边形,连接属性,管理 问题:CAD存在拓扑错误,标注位置偏移 教程:pdf ...
- C++ Primer学习笔记2--c++标准库中的 vector、string 和 bitset 类型
一.string #include <string> using std::string 初始化函数: string s1; 默认构造函数 s1 为空串 ...
随机推荐
- R语言学习-基础篇
从五月10日开始自学R in action,将我的学习所得逐渐发布在博客上. chapter1.新手上路 工作空间:存储着所有用户定义的对象(向量,矩阵,函数,数据框,列表): 当前的工目录保存是R用 ...
- java布局学习 (三)
前文已经讲了常用的4个布局了,今天再介绍最后的三个布局: 5.CardLayout 6.BoxLayout 7.空白布局null (五)CardLayout 纸牌布局 首先这种布局不是二维布局,而 ...
- FC400A与400B的区别
FC400B就比400A多了一个功能,那就是联动,也就是说主机关了后,电子净化箱也会被关掉,这样就不需要去手动关闭电源,更加方便,估计是很多工业企业上需要这样的功能,所以就升级了这么个版本.
- python之haproxy配置文件操作(第三天)
作业: 对haproxy配置文件进行操作 要求: 对haproxy配置文件中backend下的server实现增删改查的功能 一.这个程序有二个版本 1. python2.7版本见haproxy_py ...
- 初始angular框架(1)
作为一个从来没有使用过的angular框架的小白 第一步肯定是 看文档! 没错就是看文档了!
- 161223、mysql锁的两个例子
版本:mysql5.5.52 存储引擎:InnoDB 隔离级别:READ-COMMITTED 示例一: 事务1:左图 事务2:右图 1. 事务2中属于快照读,基于多版本的并发控制协议--MV ...
- javascript 使用方法名作为参数
Example <!DOCTYPE html> <html lang="en"> <head> <meta charset="u ...
- mysql 主命令总结
mysql 登录和恢复命令 mysqladmin 管理 mysql 命令 mysqldump 备份命令 mysqlbinlog 解析 binlog 命令 source 恢复数据命令
- JavaScriptCore 使用
JavaScriptCore JavaScriptCore是webkit的一个重要组成部分,主要是对JS进行解析和提供执行环境.代码是开源的,可以下下来看看(源码).iOS7后苹果在iPhone平台推 ...
- args[0]
java程序有一个主方法,是这样的public static void main(String [] args)你说的args[0]就是你用命令行编译运行java程序时,传入的第一个参数,比如你运行一 ...