简介
阅读 STL源码剖析
-
STL6大组件的交互关系
Container 通过 Allocator 取得数据存储空间, Algorithm 通过 Iterator 存取 Container 的内容, Functor(仿函数)可以协助Algorithm完成不同的策略变化, Adapter 可以修饰或嵌套Functor. -
GNU 的由来
GNU is not UNIX. UNIX 是闭源的.
- stl_config.h
根据编译器对C++进行了配置. 以宏定义的方式.
- partial specialization (偏特化设计)
简单来说, 如果单纯只用C++的模板来进行设计, 可能会出现对于指针的无法推到或者叽叽歪歪的问题.
#include <iostream>
using namespace std;
// 一般化设计
template<class I, class O>
struct testClass {
testClass() {cout << "I O" << endl;}
};
// 特殊化设计
template <class T>
struct testClass<T*, T*>
{
testClass() {
cout << "T*, T*" << endl;
}
};
// 特殊化设计
template <class T>
struct testClass<const T*, T*> {
testClass () {
cout << "Cosnt T*, T*" << endl;
}
};
int main() {
testClass<int, char> obj1;
testClass<int*, int*> obj2;
testClass<const int*, int *> obj3;
}
对于仿函数 functor 有一种方式是使用 重载 operator()实现
参考链接
https://www.cnblogs.com/yanglf/archive/2013/04/23/3037162.html
#include <iostream>
using namespace std;
template <class T>
struct pplus
{
T operator()(const T &x, const T &y) const
{
return x + y;
}
};
template <class T>
struct mminus
{
T operator()(const T &x, const T &y) const
{
return x - y;
}
};
int main()
{
pplus<int> plusobj;
mminus<int> minusobj;
//使用仿函数,就像使用函数一样
cout << plusobj(3, 5) << endl;
cout << minusobj(3, 5) << endl;
//直接产生仿函数的临时对象,并调用之
cout << pplus<int>()(43, 50) << endl;
cout << mminus<int>()(43, 50) << endl;
system("pause");
return 0;
}
重载 ++ 前置与后置
#include <iostream>
using namespace std;
class INT {
friend ostream& operator<<(ostream& os, const INT& i);
public:
INT(int i) : m_i(i) { };
// prefix : increment and then fetch
INT & operator++(){
++(this->m_i);
return *this;
}
// postfix : fetch and then increment
const INT operator++(int) {
INT temp = *this;
++(*this);
return temp;
}
// prefix : decrement and then fetch
INT & operator--(){
--(this->m_i);
return *this;
}
// postfix : fetch and then decrement
const INT operator--(int) {
INT temp = *this;
--(*this);
return temp;
}
int & operator*() const {
return (int&)m_i; // 将 const int 转为 non-const lvalue.
}
private:
int m_i;
};
ostream& operator<<(ostream& os, const INT& i) {
os << '[' << i.m_i << ']';
return os;
}
int main() {
INT I(5);
cout << I++;
cout << ++I;
cout << I--;
cout << --I;
cout << *I;
}
从这里也可以看出, 友元函数, 可以访问私有变量. 这就是友元函数的作用.
前置与后置的区别之一是有没有参数. 还有返回的对象是什么.
这样对于 那些模糊不清的 ++-- 有了更深刻的认识.
find 迭代器 start() end() 为什么是 [) 区间
template <class _InputIter, class _Tp>
inline _InputIter find(_InputIter __first, _InputIter __last,
const _Tp& __val,
input_iterator_tag)
{
while (__first != __last && !(*__first == __val)) // 只要指针不等于最后一个指针就开始迭代运行. 简介明了.
++__first;
return __first;
}
STL 的设计思维
将数据容器 和 算法 分开, 彼此独立设计, 最后再以胶着计 进行粘结.
最常用的迭代器相应型别有5中: value type, different type, pointer, reference, Iterator catagoly.
value type 是迭代器所指对象的类型.
different type 是两个迭代器之间的距离.
reference 返回值的萃取?
Item & operator*() const {return *ptr;} // referece
Iten * operator->() const {return ptr;} // pointer
迭代去被分成5类
input iterator: 这种迭代器所值得对象不允许外接改变
output iterator : 只允许写
Forward Iterator : 允许写入型算法 replace
bidirectionaliterator : 可以双向移动的.
Random Access Iterator: 涵盖所有的算术能力
---------------------------我的天空里没有太阳,总是黑夜,但并不暗,因为有东西代替了太阳。虽然没有太阳那么明亮,但对我来说已经足够。凭借着这份光,我便能把黑夜当成白天。我从来就没有太阳,所以不怕失去。
--------《白夜行》