天天看点

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

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. plauger的stl库,如下是摘抄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>,定义stl中pair模版类和相关的函数,我们常用的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的一个临时对象(当然可以直接返回值优化掉,不用担心),根据文件最后的注释,发现这个pair是1994年hp定义的版本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_t为int类型

typedef streampos wstreampos;,

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

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

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

8:<xutility>文件内#include <climits>,#include <utility>,这个文件比较长,主要声明的是迭代器相关类// template class iterator

template<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_compare,fill,equal,mismatch,copy_backward等函数

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

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

// template class auto_ptr

template<class _ty>

     class auto_ptr;

     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

     class auto_ptr

         {    // wrap an object pointer to ensure destruction

public:

     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));

         operator auto_ptr_ref<_other>() _throw0()

         {    // convert to compatible auto_ptr_ref

         return (auto_ptr_ref<_other>(*this));

         auto_ptr<_ty>& operator=(auto_ptr<_other>& _right) _throw0()

         {    // assign compatible _right (assume pointer)

         reset(_right.release());

          return (*this);

         auto_ptr(auto_ptr<_other>& _right) _throw0()

         {    // construct by assuming pointer from _right

     auto_ptr<_ty>& operator=(auto_ptr<_ty>& _right) _throw0()

         return (*this);

     auto_ptr<_ty>& operator=(auto_ptr_ref<_ty>& _right) _throw0()

         {    // assign compatible _right._ref (assume pointer)

         reset(_right._ref.release());

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

继续阅读