閱讀413 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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. 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 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_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_ptr
template<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 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));
         }

     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

 

最後更新:2017-04-02 00:06:15

  上一篇:go C++編譯時間過長解決方案
  下一篇:go ASP.NET入門隨想之抽象的力量