CONTENTS
备注:
本读书笔记基于侯捷先生的《STL源码剖析》,截图和注释版权均属于原作者所有。
本读书笔记中的源码部分直接拷贝自SGI-STL,部分代码删除了头部的版权注释,但代码版权属于原作者。
小弟初看stl,很多代码都不是太懂,注释可能有很多错误,还请路过的各位大牛多多给予指导。
std::allocator
我们以vector为例子,看下它的默认的allocator是什么。我们首先看下 vector ,里面什么也没有,但是有一行:
#include <bits/stl_vector.h>
然后我们再看下 stl_vector.h ,部分内容如下:
template<typename _Tp, typename _Alloc = std::allocator<_Tp> > class vector : protected _Vector_base<_Tp, _Alloc> 。。。。。
通过这个我们可以知道vector默认的allocator是std::allocator,也可以大致的推断出其他的容器应该也是这个。
我们打开 allocator.h ,部分内容如下:
// Define the base class to std::allocator. #include <bits/c++allocator.h> _GLIBCXX_BEGIN_NAMESPACE(std) template<typename _Tp> class allocator: public __glibcxx_base_allocator<_Tp> 。。。。
通过这里我们可以知道std::allocator就在这个文件中,继承自【 __glibcxx_base_allocator 】。这里我们先跳过这个文件,继续include。
我们打开 c++allocator.h ,部分内容如下:
#include <ext/new_allocator.h> #define __glibcxx_base_allocator __gnu_cxx::new_allocator
这里我们知道【 __glibcxx_base_allocator 】其实就是【 __gnu_cxx::new_allocator 】,继续,
打开 new_allocator.h ,部分内容如下:
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) template<typename _Tp> class new_allocator { 。。。。。
看到这里我们就可以大致的知道stl中的默认allocator的继承关系和代码位置了。然后我们开始注释代码(去掉了头部版权注释):
new_allocator.h:
#include <new> #include <bits/functexcept.h> #include <bits/move.h> //在命名空间__gnu_cxx中 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) using std::size_t; using std::ptrdiff_t; /** * @brief An allocator that uses global new, as per [20.4]. * @ingroup allocators * * This is precisely the allocator defined in the C++ Standard. * - all allocation calls operator new * - all deallocation calls operator delete */ //《STL源码剖析》P43页对此作了简要介绍,根据C++标准,如下typedef和函数是必须定义的。 template<typename _Tp> class new_allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; template<typename _Tp1> struct rebind { typedef new_allocator<_Tp1> other; }; new_allocator() throw() { } new_allocator(const new_allocator&) throw() { } template<typename _Tp1> new_allocator(const new_allocator<_Tp1>&) throw() { } ~new_allocator() throw() { } pointer address(reference __x) const { return &__x; } const_pointer address(const_reference __x) const { return &__x; } // NB: __n is permitted to be 0. The C++ standard says nothing // about what the return value is when __n == 0. pointer allocate(size_type __n, const void* = 0) { if (__n > this->max_size()) std::__throw_bad_alloc(); //申请空间时直接调用operator new,也就是我们平常使用的new操作符,申请空间 return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } // __p is not permitted to be a null pointer. void deallocate(pointer __p, size_type) { ::operator delete(__p); }//申请空间时直接调用operator delete,也就是我们平常使用的delete操作符,释放空间 size_type max_size() const throw() { return size_t(-1) / sizeof(_Tp); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); }//调用placement new,相当于在已有内存上直接调用构造函数 #ifdef __GXX_EXPERIMENTAL_CXX0X__ template<typename... _Args> void construct(pointer __p, _Args&&... __args) { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); } #endif void destroy(pointer __p) { __p->~_Tp(); }//直接调用实例的析构函数 }; template<typename _Tp> inline bool operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) { return true; } template<typename _Tp> inline bool operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) { return false; } _GLIBCXX_END_NAMESPACE
发表评论