STL学习笔记一(深入VC之STL系列)

    技术2022-05-11  122

    STL文件组成(<>的目的是为了更好的说明其文件特性)

    1<climits>内中包含limits.h文件,在limits.h文件内,定义了每种内置类型的bit,字节,最大最小数等,部分内容如下。

    #define CHAR_BIT      8         /* number of bits in a char */#define SCHAR_MIN   (-128)      /* minimum signed char value */

    #define INT_MIN     (-2147483647 - 1) /* minimum (signed) int value#define INT_MAX       2147483647    /* maximum (signed) int value */其中还包括#include <yvals.h>,这个文件是Microsoft需要的文件,具体内容和STL有关

    #if defined(__cplusplus)  #define _STD_BEGIN   namespace std {  #define _STD_END     }  #define _STD     ::std::就是定义std宏。

    这个文件中还定义vc编译器需要的环境变量,库(在其他文件内声明#include <use_ansi.h>),_Lockit类,  _Mutex类,线程等

    VC7.1中使用的STL依然是P.J. PlaugerSTL库,如下是摘抄climits文件内的版权说明,本来偶还认为从VC7.0开始,就是用自己开发的STL库,原来还是使用的P.J.Plauger版本的STL库,不知道VC8.0有没有改变

    /* * Copyright (c) 1992-2002 by P.J. Plauger.  ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V3.13:0009 */

    2<utility>,定义STLpair模版类和相关的函数,我们常用的make_pair函数就是在这个文件中定义,其原型为

    template<class _Ty1,     class _Ty2> inline     pair<_Ty1, _Ty2> __cdecl make_pair(_Ty1 _Val1, _Ty2 _Val2)     {    // return pair composed from arguments     return (pair<_Ty1, _Ty2>(_Val1, _Val2));     }

    可见是返回pair的一个临时对象(当然可以直接返回值优化掉,不用担心),根据文件最后的注释,发现这个pair1994HP定义的版本STL(好老啊)

    文件中还包括#include <iosfwd>

    3: <cstdio>,内部包括stdio.h文件,并在cstdio中声明using ::size_t;等,同时文件也包括#include <yvals.h>microsoft定义的一个文件,里面有很多宏定义,决定如何STL使用,在后面的很多文件内都包含此文件,将不在一一列出。

    4<cstring>,内部包含string.h文件,此文件内定义的是操作字符串的函数集,在此文件内,大部分宏的声明与stdio.h文件内的宏声明相同。不知道为什么ms要如此做,这里声明了我们常用的strcmp,strstr,memcpy等函数

    5<iosfwd>,内部包括#include <cstdio>#include <cstring>#include <cwchar>#include <xstddef>,内部声明模版fpos类(TEMPLATE CLASS fpos (from <streambuf>))并声明streampos,其原形为 typedef fpos<mbstate_t> streampos; // 其中mbstate_tint类型typedef streampos wstreampos;

    之后声明模版类char_traits(TEMPLATE STRUCT char_traits (FROM <string>)), 然后有charwchar的两个特化char_traits,最后声明各种i/o操作的类,根据iosfwd的名字我们不难推断出来(fwdforword的缩写),这个文件是为了提前声明io操作的文件,以方便编译使用。

    6<cwchar>,内部包含wchar.h文件,主要定义了关于操作宽字符的函数,宏,类型等

    7<xstddef>,定义一些宏,主要是异常宏的声明,内部包含stddef.h文件,此文件中主要定义一些公共宏,函数和类型

    8<xutility>文件内#include <climits>#include <utility>,这个文件比较长,主要声明的是迭代器相关类// TEMPLATE CLASS iteratortemplate<class _Category,     class _Ty,     class _Diff = ptrdiff_t,     class _Pointer = _Ty *,     class _Reference = _Ty&>         struct iterator     {    // base type for all iterator classes     typedef _Category iterator_category;     typedef _Ty value_type;     typedef _Diff difference_type;     typedef _Diff distance_type;     // retained     typedef _Pointer pointer;     typedef _Reference reference;     };

    还有一些对比函数比如lexicographical_comparefillequalmismatchcopy_backward等函数

    9<iterator>迭代器类中主要包含文件就是#include <xutility>,此类中定义迭代器类front_insert_iteratorback_insert_iteratorinsert_iterator

    10<memery>类包含#include <iterator>#include <xmemory>memery类中定义大量操作内存的函数,大部分函数都是STL内部调用。不过这里面有一个我们非常熟悉的模版类auto_ptr

    // TEMPLATE CLASS auto_ptrtemplate<class _Ty>     class auto_ptr; template<class _Ty>     struct auto_ptr_ref         {    // proxy reference for auto_ptr copying     auto_ptr_ref(auto_ptr<_Ty>& _Right)         : _Ref(_Right)         {    // construct from compatible auto_ptr         }     auto_ptr<_Ty>& _Ref;   // reference to constructor argument     }; template<class _Ty>     class auto_ptr         {    // wrap an object pointer to ensure destructionpublic:     typedef _Ty element_type;     explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()         : _Myptr(_Ptr)         {    // construct from object pointer         }

         auto_ptr(auto_ptr<_Ty>& _Right) _THROW0()         : _Myptr(_Right.release())         {    // construct by assuming pointer from _Right auto_ptr         }

         auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()         : _Myptr(_Right._Ref.release())         {    // construct by assuming pointer from _Right auto_ptr_ref         }

         template<class _Other>         operator auto_ptr<_Other>() _THROW0()         {    // convert to compatible auto_ptr         return (auto_ptr<_Other>(*this));         }

         template<class _Other>         operator auto_ptr_ref<_Other>() _THROW0()         {    // convert to compatible auto_ptr_ref         return (auto_ptr_ref<_Other>(*this));         }

         template<class _Other>         auto_ptr<_Ty>& operator=(auto_ptr<_Other>& _Right) _THROW0()         {    // assign compatible _Right (assume pointer)         reset(_Right.release());          return (*this);         }

         template<class _Other>         auto_ptr(auto_ptr<_Other>& _Right) _THROW0()         : _Myptr(_Right.release())         {    // construct by assuming pointer from _Right         }

         auto_ptr<_Ty>& operator=(auto_ptr<_Ty>& _Right) _THROW0()         {    // assign compatible _Right (assume pointer)         reset(_Right.release());         return (*this);         }

         auto_ptr<_Ty>& operator=(auto_ptr_ref<_Ty>& _Right) _THROW0()         {    // assign compatible _Right._Ref (assume pointer)         reset(_Right._Ref.release());         return (*this);         }

         ~auto_ptr()         {    // destroy the object         delete _Myptr;         }     _Ty& operator*() const _THROW0()         {    // return designated value         return (*_Myptr);         }

         _Ty *operator->() const _THROW0()         {    // return pointer to class object         return (&**this);         }

         _Ty *get() const _THROW0()         {    // return wrapped pointer         return (_Myptr);         }

         _Ty *release() _THROW0()         {    // return wrapped pointer and give up ownership         _Ty *_Tmp = _Myptr;         _Myptr = 0;         return (_Tmp);         }

         void reset(_Ty* _Ptr = 0)         {    // destroy designated object and store new pointer         if (_Ptr != _Myptr)              delete _Myptr;         _Myptr = _Ptr;         }private:     _Ty *_Myptr;  // the wrapped object pointer     };

    通过源代码分析,我们可以看到auto_ptr并没有什么神秘的,他定义一个代理对象保存其指针对象(当然也可以不这么做),并且通过源代码我们就可以清楚认识到对象所有权的转移,如果使用boostshared_ptr(使用引用计数机制)就不会有对象所有权的转移,这里唯一需要解释的是在一些类的定义前面有这么一句template<class _Other>,在函数前使用template<class _Other>的目的就是可以使auto_ptr接受(处理)不同于原类型的指针或者auto_ptr对象,这种限制在类的继承体系中十分有用,具体参考2

     

    最新回复(0)