源码之前,了无秘密
你应具备的基础
- C++ 基本语法
- 模板(Templates)基础令你事半功倍
- 数据结构(Data Structures)和算法(Algorithms)概念令你如鱼得水
标准库版本,Visual C++
VC 6.0
标准库版本,GNU C++
GNU 4.9.2 路径
8. 源码之分布(VC, GCC)
Xcode 8的源码路径/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
MinGW的源码路径MinGW\lib\gcc\mingw32\5.3.0\include\c++
9. OOP vs. GP
OOP 企图将 datas 和 methods 关联在一起
GP 却是将 data 和 methods分开来
采用 GP:
- Containers 和 Algorithms 团队可各自闭门造车,其间以 Iterator 沟通即可。
- Algorithms 通过 Iterator 确定操作范围,并通过 Iterators 取 Container 元素。
石头如何比大小,由石头决定。这就是操作符重载。
所有 Algorithms,其内最终涉及元素本身的操作,无非就是比大小。
10. 技术基础:操作符重载 and 模板(泛化
Operator Overloading,操作符重载
When an operator appears in an expression, and at least one of its operands has a class type or an enumeration type, then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following:
Overloaded operators
有四个操作符不能被重载
::
.
.*
?:
**
<>
&|
也不能重载
Iterator 的操作符重载
template<class T, class Ref, class Ptr>
struct __list_iterator {
typedef __list_iterator<T, Ref, Ptr> self;
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef __list_node <T> *link_type;
link type node;
reference operator*() const { return (*node).data; }
pointer operator->() const { return &(operator*()); }
self &operator++() {
node = (link_type) ((*node).next);
return *this;
}
self operator++(int) {
self tmp = *this;
++*this;
return tmp;
}
//……
};
Class Templates,类模板
Function Templates,函数模板
typename 和 class 功能完全相同,早期用 class,用 typename 更形象。
编译器对 function template 进行实参推导(argument deduction)
因为有实参推导,所以用函数时不需要写<>
而声明时需要写<>
Member Templates 成员模板(未讲,接触不到)
Specialization,特化
Partial Specialization,局部特化或偏特化
11. 分配器 allocators
先谈 operator new() 和 malloc()
不建议去用,是给容器用的
申请内存到最后都会跑到 malloc() 函数
VC6 STL 对 allocator 的使用
<xmemory>
allocator<typename>()变成一个 Object
分配的空间浪费比较大
没有任何特殊设计
BC5 STL 对 allocator 的使用
Borland C++
<memory.stl>
G2.9 标准库 对allocator 的使用
<stl_alloc.h>
很巧妙,可以节省cookie的空间
G4.9 标准库 对allocator 的使用
没有任何特殊设计
可以用2.9的 alloc
__gnu_cxx::__pool_alloc
12. 容器- 结构与分类
这里所谓的衍生,并非继承,而是复合关系
13. 深度搜索 list 上
尽量不要使用 void* 未定义类型的指针
++的重载
self operator++(int){} //后++
self& operator++(){} //前++
self tmp=*this; // 先调用拷贝构造函数,把*this 整体传递给拷贝构造函数
不可以连续两次后++
所以传回的不是引用
可以连续两次前++,所以传引用
14. 深度搜索 list 下
Iterator 需要遵循的原则
萃取 traits 特性
分类 category 有的只能前进,有的可以++--,有的可以跳着走
Iterator 要能回答算法的问题,共有5种。
- category
- difference
- value type
- reference
- pointer
后两种从来没用过。
所以 iterator 必须要定义这五种
iterator_traits
Iterator Traits 用以分离 class iterators 和 non-class iterators
完整的 iterator_traits
各式各样的 traits
- type traits
- iterator traits
- char traits
- allocator traits
- pointer traits
- array traits
容器 vector
两倍增长
vector's iterator
容器 array
typedef int T[100];