Stanford CS106L:标准C++程序设计
流 Stream
stream 相当于缓冲区 buffer,在不同物件中传输数据
构造 stringstream
|
四个 bits:
- Good:准备好读写
- Fail:之前的操作失败了
- EOF:之前的操作到达了 buffer 的末尾
- Bad:外部错误
通常检查 EOF
和 Fail
位的状态
不要大量使用 std::endl
,因为每次使用时都会清除一次 buffer,导致效率低下,改为 \n
。
还有很多 manipulator 可供使用,例如控制格式的 endl
,hex
,setprecision
,fixed
,fill
,boolalpha
,还有调整指针在 buffer 中的位置的 iss.tellp()
,oss.tellg()
,iss.seekp(pos)
,oss.seekg(pos)
等
类型 Type
auto
可以用于代替比较长且类型不重要的类型名。
pair
可用于两个变量,tuple
为三个
|
传递函数参数时,若数据量较大,可使用&
引用变量,而不是复制一份。
c++ 初始化方法过多,可使用统一初始化法,即使用初始化表 initializer_list,例如 vector<int> vec{1, 2, 3};
,Course now{"CS106L", {15, 30}, {16, 30}};
,结构体内的变量按照定义顺序赋值。
注意:
vector<int> vec(3); // vec = {0, 0, 0}
vector<int> vec{3}; // vec = {3}
序列容器 Sequence Container
包括 vector
,deque
,list
(双链表),array
,forward_list
(单链表)
因为本质上使用的是 vector 和 deque,所以 stack
和 queue
也被成为容器适配器 Container Adaptor
关联容器 Associative Container 和 迭代器 Iterator
包括 map
,set
,unordered_map
,unordered_set
unordered_map 和 map 的区别
- 实现不同
unordered_map 底层是用哈希表实现的
map 底层是用红黑树实现的 - 性能不同
unordered_map 是不按键值排序的,插入的时间是 O(logn),查询时间是 O(1)
map 是按键值排序的,插入的时间是 O(logn),查询时间是 O(logn)
高级容器 Advanced Container 有 multi_map
和 multi_set
迭代器 Iterator用于访问容器
for(auto it:v)
的本质就是使用迭代器
iterator 有 5 种类型:
- Input 输入
- Output 输出
- Forward 前向
- Bidirectional 双向
- Random Access 随机读写
关系如下:
graph LR 随机读写 --> 双向 --> 前向 --> 输入 & 输出
模板 Template
|
实质是在编译时智能将 T
替换为 int
、double
等,这种叫作泛型函数 generic function。
但是类型 T 必须满足一定条件,例如可比较大小,但没有写出来,这叫作隐式接口 implicit interface
C++20 提供的 Concept 可将隐式接口转化为显示接口 explicit interface
函数 Function 和算法 algorithm
lambda 函数相当于写在一行内的轻量化函数
|
predicate
是一个接收一些参数并返回一个 boolean
值的函数,例如:
|
这样即可将函数作为参数传递。
算法有 sort
、nth_element
、stable_partition
、copy_if
、remove_if
等
运算符 Operator
c++ 中可重载的运算符:
算术 | 位 | 关系 | 流 | 逻辑 | 增加 | 内存 | 其它 | |
---|---|---|---|---|---|---|---|---|
+ |
+= |
& |
== |
<< |
&& |
++ |
-> |
() |
- |
-= |
| |
!= |
>> |
|| |
-- |
->* |
[] |
* |
*= |
~ |
< |
<<= |
^ |
new |
, |
|
/ |
/= |
! |
> |
>>= |
&= |
new [] |
= |
|
<= |
|= |
delete |
||||||
>= |
^= |
delete [] |
||||||
<=> |
重载时遵循以下规则:
[]
、()
、->
、=
、++
重载为成员函数<<
重载为非成员函数- 若两个值平等,如
+
,重载为成员函数;若不平等,如+=
,重载为非成员函数
重载了 <
后可将剩下几个关系符一起重载:
|
特殊的成员函数 Special Function
以下特殊的成员函数一般要重载:
- 没有参数的生成对象
- 以已有的对象生成另一个对象
- 复制并替换原有对象的内容
- 销毁
也可以 函数声明 = delete;
销毁特定函数
移动语义 Move Semantic
l-value 是有名称的表达式,可以用 &
获取地址;
r-value 是没有名称的表达式,是临时的值,无法用 &
获取地址,只能出现在赋值语句右边。
例如 swap()
函数可以优化:
|
继承 Inheritance
|
资源获取就是初始化 RAII 和智能指针 Smart Pointer
防止因程序意外停止运行而导致的内存泄漏,解决方法的本质为调用时构造对象,后析构对象
不要这么做:
|
改为:istream input("in.txt");
同样,避免使用 new
和 delete
,使用 unique_ptr
、shared_ptr
、weak_ptr
等(在头文件 memory
中),例如std::unique_ptr<int> p = std::make_unique<int>();
模板元编程 Template Metaprogramming
对值的计算:
|
对于类型,有:
|