目录
一、IO库
1.头文件
<iostream>:定义了读写流的类型:istream, ostream, iostream, wistream, wostream, wiostream
<fstream>:读写命名文件的类型:ifstream, ofstream, fstream, wifstream, wofstream, wfstream
<sstream>:读写内存 string 对象的类型:istringstream, ostringstream, stringstream
<fstream> 和 <sstream> 中的类型都继承自 iostream 中的类型。可以将一个派生类对象当成基类对象来使用。
所有这些输入输出流对象的 >> 操作都是读取一个单词。
2. 不能拷贝或对 IO 对象赋值,因此也不能将形参或返回类型设置成流类型。
进行 IO 操作的函数通常以引用形式传递和返回流。读写 IO 对象会改变其状态,因此引用不能是 const 的。
3. 使用一个流之前,应该先检查它是否处于良好状态;条件状态用来查看流的状态。
while(cin >> word);// >> 表达式返回流的状态
while(cin.good());// 意义同上
while(!cin.fail());// 意义同上。
4. 缓冲刷新(即数据真正写到设备或文件 “打印”)的原因:
◇ 程序正常结束,比如执行到了 return。
◇ 缓冲区满了
◇ 使用操纵符如 endl, flush, ends 来显示刷新缓冲区
◇ 当读写被关联的流时,如读 cin 或写 cerr 都会刷新 cout 的缓冲区
◇ 使用操纵符 unitbuf 设置流的内部状态来清空缓冲区。
4. 输入流和输出流可以相关联,使用函数 tie() 来将一个输入流关联到一个输出流。
5. 文件打开模式中使用 app 模式可以避免清空文件内容
◇ 每个流对象都有默认的文件模式,ifstream 默认 in 模式打开文件,ofstream 默认 out,fstream 默认 in 和 out。
◇ 对 ifstream 对象不能设置 out 模式,对 ofstream 对象不能设置 in 模式
◇ 默认情况下以 out 模式打开文件会使文件内容被清空
6. 打开文件后可以使用 fs.is_open() 来检查是否打开成功。
#include<fstream>
fstream fs;
// 创建一个未绑定的文件流 fs
fstream fs('data.txt');
// 创建一个绑定到文件 data.txt 的文件流 fs,并打开文件 data.txt
fstream fs('data.txt', mode);
// 与上一个构造函数类似,但是按指定模式 mode 打开文件
7. 定义一个 istringstream 对象时要提供一个字符串初始值,因为它是输入流,内部要保存了字符串才能输入到变量。或者使用一个 sstrm.str(s)来将一个string对象拷贝到输入流 sstrm 内部。
二、顺序容器
1. 没有更好的选择,就用vector
2. 需要随机访问,就用 vector / deque
三、泛型算法
1.
算法在哪两个头文件中?
<algorithm> 和 <numeric>
2. 静态内存用来存储:
(1)局部static对象第一次定义时被初始化,程序终止才被销毁
(2)类的static成员,可以是public、private的
栈用来存储局部非static对象
程序用堆来存储动态分配,
四、动态内存
(一)new
1. 通常说用new T[ ] 分配的内存为 “ 动态数组 ” ,但实际上是得到一个数组元素类型的指针
int *p = new int[n];
|n可以从函数中得来,但必须为Int,同时可以为0
delete [] p;
|因为p是数组
delete p;
|若P是一个动态分配的对象
2. new在动态内存中为对象分配空间并返回一个指向该对象的指针,使用 delete 手动释放内存,很危险。
- new:在堆中为对象分配空间并返回指向该对象的指针
- delete:接受一个动态对象的指针,销毁该对象并释放内存。
忘记释放内存会引起内存泄漏,释放了后继续引用指针会引用非法内存。
如果忘记释放内存,在程序结束时会由操作系统自动回收。
4. new 分配的对象没有名字,只有指向它的指针,因为它将内存分配和对象构造结合在一起了。如果不提供初始值,new 分配的对象会进行默认初始化。
两种智能指针是更好的替代方式:shared_ptr、unique_ptr
4. 析构函数:每个类都有析构函数,析构函数是特殊的成员函数。析构函数控制对象销毁时执行什么操作,析构函数一般用来释放对象分配的资源。
(二)allocator
1. allocator的性能比new更好、更灵活。会根据给定的对象类型来确定适当的大小和对齐位置
2. allocator定义在 < memory >中
#include <string>
#include <memory>
using std::allocator;
allocator<string> alloc;
| 初始化n个未初始化的string
auto const p = alloc.allocate(n);
| p 是一个 string* 指针,指向原始内存。arg 被传递给 string 的构造函数,用来在 p 指向的内存中构造对象。
alloc.construct(p, args);
| p 是一个 string* 指针,此算法对 p 指向的对象执行析构函数
alloc.destroy(p);
| 释放从 p 开始的长度为 n 的内存。p 是一个 allocate() 返回的指针,n 是 p 创建时要求的大小。
| 在 deallocate 之前必须先 destroy 掉这块内存中创建的每个对象。
alloc.deallocate(p, n);
construct函数用来在allocate返回的内存中,构造元素
destroy用来销毁用完的对象,且dellocate必须在destroy之后