本部分将剩余视频内容整合在一起,因为后面有很多缺失的部分:unordered_container缺失了一部分,forward_list缺失,shared_ptr缺失,type traits缺失。
一、标准库容器结构
其中标红的三个是C++11新增加的容器,其中array和forward_list比较简单,unordered_containers比较重要,可惜缺失了很多内容。
1. array
其实里面只是一个C语言的数组,只是包装成了一个class的样子。下面是TR1版本(C++03)的源代码,简洁易懂:
template<typename _Tp, std::size_t _Nm>
struct array
{
typedef _Tp value_type;
typedef _Tp* pointer;
typedef value_type* iterator;
value_type _M_instance[_Nm ? _Nm : 1];
iterator begin()
{ return iterator(&_M_instance[0]); }
iterator end()
{ return iterator(&_M_instance[_Nm]); }
......
};
注意里面并没有构造函数和析构函数。
与TR1版本不同,GCC4.9array的源码相当复杂,不容易读懂,见视频,这里就不截图了。
2. 容器hashtable
注意这部分并不是新东西,老师也只简单介绍了原理:其实就是使用链地址法解决冲突的哈希表,key的计算方式是对哈希表长度取余,哈希表长度是一个素数。如果hash表放不下了,就要进行rehashing,将哈希表扩容为大概原先的两倍,当然扩容以后也得是个素数。
hashtable里面的key虽然是数字,但里面其实什么对象都能放,只是我们需要告诉它hashfunction是什么,我把hashfunction理解为一个怎样讲对象计算为一个数字的函数。当然最好一个对象能够唯一地对应一个数字。
3. hashfunction
(1)标准库的hashfunction的用法
上图是标准库已有的hashfunction,可以将一些类型转化为size_t的数值。其中hash<T>代表一个类型,所以hash<T>()就是一个临时对象,并且这是个可调用对象。
(2)标准库的hashfunction定义的逻辑
以GCC2.9的定义为例:
//泛化版本
template <class Key> struct hash { };
//很多特化版本
_STL_TEMPLATE_NULL struct hash<char>{ //_STL_TEMPLATE_NULL就是template<>
size_t operator()(char x) const { return x; }
};
_STL_TEMPLATE_NULL struct hash<short>{
size_t operator()(short x) const { return x; }
};
_STL_TEMPLATE_NULL struct hash<unsigned short>{
size_t operator()(unsigned short x) const { return x; }
};
.......
基本逻辑是定义一个空的泛化版本,然后针对各种类型再定义特化的版本。GCC4.9的实现要复杂得多,并且不仅仅定义了整型的hashfunction,还有指针类型,float,double等等等等,但是结构复杂,具体实现原理也不明,有兴趣可以去看PPT。class string之类也有自己的hashfunction,但是是和string定义在一起的。
(3)定义自己的hashfunction——一个万用的hashfunction(本部分内容缺失,有空对着PPT学一下)