Tips:
- Generic Programming 將算法和數據結構分開,讓其可以獨立設計。
- 所有算法最終就是在比大小。
- 操作符重載和模板在STL中占相當重要的位置。
- STL是主要是使用 Generic Programming 的方式實現的
1. Befor All
-
STL六大部件關系
-
“前閉后開”區間
STL中的容器均為此類空間。
2. 分配器 allocators
- 不建議直接使用,因為其使用方法很不友好。
- 作為容器的基礎支持部分,其優劣十分重要,若質量太差會造成效率大幅降低。
- C++中所有申請內存都會調用
malloc()
,而malloc()
得到的內存會附帶一定的 overhead ,當數據本身較小時,空間浪費較嚴重。 - allocator 最重要的兩個函數:
allocate
和deallocate
。前者申請內存,后者釋放內存。 - 多數實現的 allocator 以
::operator new()
和::operator delete()
完成allocate
和deallocate
,沒有任何特殊設計。
實現(以VC6為例)
#ifndef _FARQ
#define _FARQ
#define _PDFT ptrdiff_t
#define _SIZT size_t
#endif
#define _POINTER_X(T,A) T_FARQ*
#define _REFERENCE_X(T,A) T_FARQ&
template<typename _Ty>
class allocator
{
public:
typedef _SIZT size_type;
typedef _PDFT difference_type;
typedef _Ty _FARQ *pointer;
typedef _Ty value_type;
pointer allocate(size_type _N, const void *)
{ return (_Allcoate(difference_type(_N), pointer(0))); }
void deallocate(void _FARQ *_P, size_type)
{ operator delete(_P); }
};
template<typename _Ty>
inline _Ty _FARQ *_Allocate(_PDFT _N, _Ty _FARQ *)
{
if (_N < 0)
_N = 0;
return (_Ty _FARQ *)operator new(_SIZT(_N) * sizeof(_Ty));
}
3. 容器之間的實現關系
4. 容器 list
5. 迭代器 iterator 和 Iterator Traits
- 五個必須的
typedef
A.iterator_category
:記錄 iterator 的分類
B.value_type
:記錄數據類型
C.pointer
:記錄數據指針
D.reference
:記錄數據引用
E.difference_type
:記錄指針距離的類型 - 重載++、--操作符時:用
operator++()
、operator--()
表示前置++、--;用operator++(int)
、operator--(int)
表示后置++、--。 - 指針被視為一種退化的 iterator 。算法想要提取 iterator 的特征時可以通過 iterator traits 來識別指針和 iterator ,進而由 iterator traits回答算法。