CONTENTS
备注:
本读书笔记基于侯捷先生的《STL源码剖析》,截图和注释版权均属于原作者所有。
本读书笔记中的源码部分直接拷贝自SGI-STL,部分代码删除了头部的版权注释,但代码版权属于原作者。
小弟初看stl,很多代码都不是太懂,注释可能有很多错误,还请路过的各位大牛多多给予指导。
stl_construct.h
主要用于封装各种构造与析构函数,部分源码如下(为了节省版面,删除了头部的版权注释):
#ifndef _STL_CONSTRUCT_H #define _STL_CONSTRUCT_H 1 //这里包含了new,后面便可以使用placement new,new文件源码后面附上。 #include <new> #include <bits/move.h> //在std命名空间中 _GLIBCXX_BEGIN_NAMESPACE(std) /** * Constructs an object in existing memory by invoking an allocated * object's constructor with an initializer. */ //新实例的内存已经申请好了,这里调用构造函数将其构造好。 template<typename _T1, typename _T2> inline void #ifdef __GXX_EXPERIMENTAL_CXX0X__ // Allow perfect forwarding _Construct(_T1* __p, _T2&& __value) #else _Construct(_T1* __p, const _T2& __value) #endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_]allocator::construct ::new(static_cast<void*>(__p)) _T1(_GLIBCXX_FORWARD(_T2, __value)); //placement new,可简单的理解为 _T1(__value); } /** * Destroy the object pointed to by a pointer type. */ //析构单个实例 //只有一个入参,直接调用实例的析构函数。 template<typename _Tp> inline void _Destroy(_Tp* __pointer) { __pointer->~_Tp(); } //有两个参数,分别是头尾部[)的iterator,通过iterator的累加,分别调用一个入参的_Destroy函数进行析构 //此版本的_Destroy_aux是需要【显式的】调用析构函数的。 template<bool> struct _Destroy_aux { template<typename _ForwardIterator> static void //这里使用的是static void,这样便可以直接通过类名来调用了_Destroy_aux::,非常方便 __destroy(_ForwardIterator __first, _ForwardIterator __last) { for (; __first != __last; ++__first) std::_Destroy(&*__first); } }; //同上, //此版本的_Destroy_aux是【不需要】调用析构函数的。个人的理解是如果实例比较简单,不需要显示的调用析构函数, //那么可以进行流程的优化,省略掉调用析构函数的流程,提高运行效率。 template<> struct _Destroy_aux<true> { template<typename _ForwardIterator> static void __destroy(_ForwardIterator, _ForwardIterator) { } }; /** * Destroy a range of objects. If the value_type of the object has * a trivial destructor, the compiler should optimize all of this * away, otherwise the objects' destructors must be invoked. */ //析构多个实例,2参数版本 //这里首先对是否需要调用析构函数进行判断,如果实例比较简单(比如没有动态内存的申请),析构时无需显示调用析构函数(比如类定义时析构函数就未实现)。 //就可以进行代码优化(调用_Destroy_aux的不同版本)。 template<typename _ForwardIterator> inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) { typedef typename iterator_traits<_ForwardIterator>::value_type _Value_type; std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: __destroy(__first, __last); } /** * Destroy a range of objects using the supplied allocator. For * nondefault allocators we do not optimize away invocation of * destroy() even if _Tp has a trivial destructor. */ //如果实例不是通过默认的allocator,而是通过其他的自定义的allocator来申请的,那么在析构时就不能调用默认的析构函数了 //就必须使用自定义的allocator的析构函数,上面的注释也提到了这一点。 template <typename _Tp> class allocator; template<typename _ForwardIterator, typename _Allocator> void _Destroy(_ForwardIterator __first, _ForwardIterator __last, _Allocator& __alloc) { for (; __first != __last; ++__first) __alloc.destroy(&*__first); } //如果调用模板函数时显式的提到了allocator,但不是自定义版本的,那么底层的实现依然是默认的allocator。 //直接调用2参数版本。 template<typename _ForwardIterator, typename _Tp> inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last, allocator<_Tp>&) { _Destroy(__first, __last); } _GLIBCXX_END_NAMESPACE #endif /* _STL_CONSTRUCT_H */
new
文件部分源码如下(为了节省版面,删除了头部的版权注释):
#ifndef _NEW #define _NEW #pragma GCC system_header #include <cstddef> #include <exception> #pragma GCC visibility push(default) extern "C++" { namespace std { /** * @brief Exception possibly thrown by @c new. * @ingroup exceptions * * @c bad_alloc (or classes derived from it) is used to report allocation * errors from the throwing forms of @c new. */ //声明了一个【 bad_alloc 】异常类,用来在new/delete失败时抛出 class _GLIBCXX_IMPORT bad_alloc : public exception { public: bad_alloc() throw() { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_alloc() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); }; struct nothrow_t { }; extern const nothrow_t nothrow; /** If you write your own error handler to be called by @c new, it must * be of this type. */ typedef void (*new_handler)(); /// Takes a replacement handler as the argument, returns the /// previous handler. new_handler set_new_handler(new_handler) throw(); } // namespace std //@{ /** These are replaceable signatures: * - normal single new and delete (no arguments, throw @c bad_alloc on error) * - normal array new and delete (same) * - @c nothrow single new and delete (take a @c nothrow argument, return * @c NULL on error) * - @c nothrow array new and delete (same) * * Placement new and delete signatures (take a memory address argument, * does nothing) may not be replaced by a user's program. */ //各种重载 new/delete 运算符声明 void* operator new(std::size_t) throw (std::bad_alloc); void* operator new[](std::size_t) throw (std::bad_alloc); void operator delete(void*) throw(); void operator delete[](void*) throw(); void* operator new(std::size_t, const std::nothrow_t&) throw(); void* operator new[](std::size_t, const std::nothrow_t&) throw(); void operator delete(void*, const std::nothrow_t&) throw(); void operator delete[](void*, const std::nothrow_t&) throw(); //Placement new 和 Placement delete 函数,实现的非常简单 // Default placement versions of operator new. inline void* operator new(std::size_t, void* __p) throw() { return __p; } inline void* operator new[](std::size_t, void* __p) throw() { return __p; } // Default placement versions of operator delete. inline void operator delete (void*, void*) throw() { } inline void operator delete[](void*, void*) throw() { } //@} } // extern "C++" #pragma GCC visibility pop #endif
发表评论