<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      厚積薄發
      海納百川,有容乃大
      看到ATL中有3個類的代碼比較比較重復,在atlbase.h中,分別是CAutoVectorPtr, CAutoPtr和CAutoStackPtr,他們的功能其實很類似STL中的autoptr, 但是這里因為針對不同的分配對象而用了3個不同的類,其中CAutoVectorPtr是針對數組類型的,CAutoPtr是針對普通的非數組類型,而CAutoStackPtr針對的是_malloca分配的類型,因為最后釋放方式的不同,它這里用了3份代碼來實現。

      CAutoVectorPtr:
      template< typename T >
      class CAutoVectorPtr
      {
      public:
          CAutoVectorPtr() throw() :
              m_p( NULL )
          {
          }
          CAutoVectorPtr( CAutoVectorPtr< T >& p ) throw()
          {
              m_p = p.Detach();  // Transfer ownership
          }
          explicit CAutoVectorPtr( T* p ) throw() :
              m_p( p )
          {
          }
          ~CAutoVectorPtr() throw()
          {
              Free();
          }

          operator T*() const throw()
          {
              return( m_p );
          }

          CAutoVectorPtr< T >& operator=( CAutoVectorPtr< T >& p ) throw()
          {
              if(*this==p)
              {
                  if(m_p == NULL)
                  {
                      // This branch means both two pointers are NULL, do nothing.
                  }
                  else if(this!=&p)
                  {
                      // If this assert fires, it means you attempted to assign one CAutoVectorPtr to another when they both contained 
                      
      // a pointer to the same underlying vector. This means a bug in your code, since your vector will get 
                      
      // double-deleted. 
                      ATLASSERT(FALSE);

                      // For safety, we are going to detach the other CAutoVectorPtr to avoid a double-free. Your code still
                      
      // has a bug, though.
                      p.Detach();
                  }
                  else
                  {
                      // Alternatively, this branch means that you are assigning a CAutoVectorPtr to itself, which is
                      
      // pointless but permissible

                      
      // nothing to do
                  }
              }
              else
              {
                  Free();
                  Attach( p.Detach() );  // Transfer ownership
              }
              return( *this );
          }

          // basic comparison operators
          bool operator!=(CAutoVectorPtr<T>& p) const
          {
              return !operator==(p);
          }

          bool operator==(CAutoVectorPtr<T>& p) const
          {
              return m_p==p.m_p;
          }

          // Allocate the vector
          bool Allocate( size_t nElements ) throw()
          {
              ATLASSUME( m_p == NULL );
              ATLTRY( m_p = new T[nElements] );
              if( m_p == NULL )
              {
                  returnfalse );
              }

              returntrue );
          }
          // Attach to an existing pointer (takes ownership)
          void Attach( T* p ) throw()
          {
              ATLASSUME( m_p == NULL );
              m_p = p;
          }
          // Detach the pointer (releases ownership)
          T* Detach() throw()
          {
              T* p;

              p = m_p;
              m_p = NULL;

              return( p );
          }
          // Delete the vector pointed to, and set the pointer to NULL
          void Free() throw()
          {
              delete[] m_p;
              m_p = NULL;
          }

      public:
          T* m_p;
      };



      CAutoPtr:
      template< typename T >
      class CAutoPtr
      {
      public:
          CAutoPtr() throw() :
              m_p( NULL )
          {
          }
          template< typename TSrc >
          CAutoPtr( CAutoPtr< TSrc >& p ) throw()
          {
              m_p = p.Detach();  // Transfer ownership
          }
          CAutoPtr( CAutoPtr< T >& p ) throw()
          {
              m_p = p.Detach();  // Transfer ownership
          }
          explicit CAutoPtr( T* p ) throw() :
              m_p( p )
          {
          }
          ~CAutoPtr() throw()
          {
              Free();
          }

          // Templated version to allow pBase = pDerived
          template< typename TSrc >
          CAutoPtr< T >& operator=( CAutoPtr< TSrc >& p ) throw()
          {
              if(m_p==p.m_p)
              {
                  // This means that two CAutoPtrs of two different types had the same m_p in them
                  
      // which is never correct
                  ATLASSERT(FALSE);
              }
              else
              {
                  Free();
                  Attach( p.Detach() );  // Transfer ownership
              }
              return( *this );
          }
          CAutoPtr< T >& operator=( CAutoPtr< T >& p ) throw()
          {
              if(*this==p)
              {
                  if(this!=&p)
                  {
                      // If this assert fires, it means you attempted to assign one CAutoPtr to another when they both contained 
                      
      // a pointer to the same underlying object. This means a bug in your code, since your object will get 
                      
      // double-deleted. 
      #ifdef ATL_AUTOPTR_ASSIGNMENT_ASSERT
                      ATLASSERT(FALSE);
      #endif

                      // For safety, we are going to detach the other CAutoPtr to avoid a double-free. Your code still
                      
      // has a bug, though.
                      p.Detach();
                  }
                  else
                  {
                      // Alternatively, this branch means that you are assigning a CAutoPtr to itself, which is
                      
      // pointless but permissible

                      
      // nothing to do
                  }
              }
              else
              {
                  Free();
                  Attach( p.Detach() );  // Transfer ownership
              }
              return( *this );
          }

          // basic comparison operators
          bool operator!=(CAutoPtr<T>& p) const
          {
              return !operator==(p);
          }

          bool operator==(CAutoPtr<T>& p) const
          {
              return m_p==p.m_p;
          }

          operator T*() const throw()
          {
              return( m_p );
          }
          T* operator->() const throw()
          {
              ATLASSUME( m_p != NULL );
              return( m_p );
          }

          // Attach to an existing pointer (takes ownership)
          void Attach( T* p ) throw()
          {
              ATLASSUME( m_p == NULL );
              m_p = p;
          }
          // Detach the pointer (releases ownership)
          T* Detach() throw()
          {
              T* p;

              p = m_p;
              m_p = NULL;

              return( p );
          }
          // Delete the object pointed to, and set the pointer to NULL
          void Free() throw()
          {
              delete m_p;
              m_p = NULL;
          }

      public:
          T* m_p;
      };

      CAutoStackPtr:
      /* Automatic cleanup for _malloca objects */
      template< typename T >
      class CAutoStackPtr
      {
      public:
          CAutoStackPtr() throw() :
              m_p( NULL )
          {
          }
          template< typename TSrc >
          CAutoStackPtr( CAutoStackPtr< TSrc >& p ) throw()
          {
              m_p = p.Detach();  // Transfer ownership
          }
          CAutoStackPtr( CAutoStackPtr< T >& p ) throw()
          {
              m_p = p.Detach();  // Transfer ownership
          }
          explicit CAutoStackPtr( T* p ) throw() :
              m_p( p )
          {
          }
          ~CAutoStackPtr() throw()
          {
              Free();
          }

          // Templated version to allow pBase = pDerived
          template< typename TSrc >
          CAutoStackPtr< T >& operator=( CAutoStackPtr< TSrc >& p ) throw()
          {
              if(m_p==p.m_p)
              {
                  // This means that two CAutoPtrs of two different types had the same m_p in them
                  
      // which is never correct
                  ATLASSERT(FALSE);
              }
              else
              {
                  Free();
                  Attach( p.Detach() );  // Transfer ownership
              }
              return( *this );
          }
          CAutoStackPtr< T >& operator=( CAutoStackPtr< T >& p ) throw()
          {
              if(*this==p)
              {
                  if(this!=&p)
                  {
                      // If this assert fires, it means you attempted to assign one CAutoPtr to another when they both contained 
                      
      // a pointer to the same underlying object. This means a bug in your code, since your object will get 
                      
      // double-deleted. 
                      ATLASSERT(FALSE);

                      // For safety, we are going to detach the other CAutoPtr to avoid a double-free. Your code still
                      
      // has a bug, though.
                      p.Detach();
                  }
                  else
                  {
                      // Alternatively, this branch means that you are assigning a CAutoPtr to itself, which is
                      
      // pointless but permissible

                      
      // nothing to do
                  }
              }
              else
              {
                  Free();
                  Attach( p.Detach() );  // Transfer ownership
              }
              return( *this );
          }

          // basic comparison operators
          bool operator!=(CAutoStackPtr<T>& p) const
          {
              return !operator==(p);
          }

          bool operator==(CAutoStackPtr<T>& p) const
          {
              return m_p==p.m_p;
          }

          operator T*() const throw()
          {
              return( m_p );
          }
          T* operator->() const throw()
          {
              ATLASSUME( m_p != NULL );
              return( m_p );
          }

          // Attach to an existing pointer (takes ownership)
          void Attach( T* p ) throw()
          {
              ATLASSUME( m_p == NULL );
              m_p = p;
          }
          // Detach the pointer (releases ownership)
          T* Detach() throw()
          {
              T* p;

              p = m_p;
              m_p = NULL;

              return( p );
          }
          // Delete the object pointed to, and set the pointer to NULL
          void Free() throw()
          {
              /* Note: _freea only actually does anything if m_p was heap allocated
                 If m_p was from the stack, it wouldn't be possible to actually free it here
                 [wrong function] unless we got inlined. But really all we do if m_p is 
                 stack-based is ignore it and let its alloca storage disappear at the end
                 of the outer function.
              
      */
              _freea(m_p);
              m_p = NULL;
          }

      public:
          T* m_p;
      };

      可以看到上面代碼明顯非常重復,不知道ATL這樣寫是不是歷史原因,我們下面嘗試對它進行重構。

      可以看到其實他們只是最終釋放(Free)的時候稍微有些差別,我們明顯可以把寫差別提取出來,作為一個釋放的Policy。

      struct DeleteFunctor
      {
          template<typename T> static void Release(T* p) { delete p; }
      };

      struct DeleteArrayFunctor
      {
          template<typename T> static void Release(T* p) { delete []p; }
      };

      struct DeleteStackFunctor
      {
          template<typename T> static void Release(T* p) { _freea p; }
      };

      然后我們把上面的各種釋放行為作為一個模板參數傳進去就可以了,代碼如下:
      template< typename T, typename ReleasePolicy>
      class CAutoReleasePtr
      {
      public:
          CAutoReleasePtr() throw() :
            m_p( NULL )
            {
            }
            template< typename TSrc >
            CAutoReleasePtr( CAutoReleasePtr< TSrc >& p ) throw()
            {
                m_p = p.Detach();  // Transfer ownership
            }
            CAutoReleasePtr( CAutoReleasePtr< T >& p ) throw()
            {
                m_p = p.Detach();  // Transfer ownership
            }
            explicit CAutoReleasePtr( T* p ) throw() :
            m_p( p )
            {
            }
            ~CAutoReleasePtr() throw()
            {
                Free();
            }

            // Templated version to allow pBase = pDerived
            template< typename TSrc >
            CAutoReleasePtr< T >& operator=( CAutoReleasePtr< TSrc >& p ) throw()
            {
                if(m_p==p.m_p)
                {
                    // This means that two CAutoPtrs of two different types had the same m_p in them
                    
      // which is never correct
                    ATLASSERT(FALSE);
                }
                else
                {
                    Free();
                    Attach( p.Detach() );  // Transfer ownership
                }
                return( *this );
            }
            CAutoReleasePtr< T >& operator=( CAutoReleasePtr< T >& p ) throw()
            {
                if(*this==p)
                {
                    if(this!=&p)
                    {
                        // If this assert fires, it means you attempted to assign one CAutoPtr to another when they both contained 
                        
      // a pointer to the same underlying object. This means a bug in your code, since your object will get 
                        
      // double-deleted. 
      #ifdef ATL_AUTOPTR_ASSIGNMENT_ASSERT
                        ATLASSERT(FALSE);
      #endif

                        // For safety, we are going to detach the other CAutoPtr to avoid a double-free. Your code still
                        
      // has a bug, though.
                        p.Detach();
                    }
                    else
                    {
                        // Alternatively, this branch means that you are assigning a CAutoPtr to itself, which is
                        
      // pointless but permissible

                        
      // nothing to do
                    }
                }
                else
                {
                    Free();
                    Attach( p.Detach() );  // Transfer ownership
                }
                return( *this );
            }

            // basic comparison operators
            bool operator!=(CAutoReleasePtr<T>& p) const
            {
                return !operator==(p);
            }

            bool operator==(CAutoReleasePtr<T>& p) const
            {
                return m_p==p.m_p;
            }

            operator T*() const throw()
            {
                return( m_p );
            }
            T* operator->() const throw()
            {
                ATLASSUME( m_p != NULL );
                return( m_p );
            }

            // Attach to an existing pointer (takes ownership)
            void Attach( T* p ) throw()
            {
                ATLASSUME( m_p == NULL );
                m_p = p;
            }
            // Detach the pointer (releases ownership)
            T* Detach() throw()
            {
                T* p;

                p = m_p;
                m_p = NULL;

                return( p );
            }
            // Delete the object pointed to, and set the pointer to NULL
            void Free() throw()
            {
                ReleasePolicy::Release(m_p);
                m_p = NULL;
            }

      public:
          T* m_p;
      };

      可以看到我們上面其實就改了一行代碼,改了下最終的釋放策略.

      好,現在我們可以這樣用了:
      CAutoReleasePtr<T, DeleteFunctor> p1(new int);
      CAutoReleasePtr<T, DeleteArrayFunctor> p2(new int[10]);
      功能是可以了,但是是不是覺得上面這樣用起來不方便,typedef一下就好了:
       typedef CAutoReleasePtr<T, DeleteFunctor> CSimplePtr<T>;
       typedef CAutoReleasePtr<T, DeleteArrayFunctor> CArrayPtr<T>;
       typedef CAutoReleasePtr<T, DeleteStackFunctor> CStackPtr<T>;
      但是我們很塊發現上面的代碼編譯都過不了。

      既然typedef不行,那我們就通過繼承來生成一個新類:
      template<typename T> class CSimplePtr: public CAutoReleasePtr<T, DeleteFunctor> {};
      template<typename T> class CArrayPtr: public CAutoReleasePtr<T, DeleteArrayFunctor> {};
      template<typename T> class CStackPtr: public CAutoReleasePtr<T, DeleteStackFunctor> {};
      我們很快又發現,用不起來,我們新類的構造函數需要重寫才行。

      接下來我們考慮生成一個新類,然后在內部typedef:
       template<typename T>
       struct CSimplePtr
       {
           typedef CAutoReleasePtr<T, DeleteFunctor> type;
       };
       
       template<typename T>
       struct CArrayPtr
       {
           typedef CAutoReleasePtr<T, DeleteArrayFunctor> type;
       };
       
       template<typename T>
       struct CStackPtr
       {
           typedef CAutoReleasePtr<T, DeleteStackFunctor> type;
       };
      然后這樣用:
      CSimplePtr<int>::type p(new int);
      CArrayPtr<int>::type p1(new int[20]);
      可是這樣用和最初的用法似乎又沒多少改進....

      再最后想到了用宏:
      #define CSimplePtr(T) CAutoReleasePtr<T, DeleteFunctor>
      #define CArrayPtr(T) CAutoReleasePtr<T, DeleteArrayFunctor>
      但是用的時候太嘔心了:
      CSimplePtr(int) p(new int);
      CArrayPtr(int) p1(new int[20]);

      最后,實在沒有什么辦法了....
      不知道大家有沒有什么好方法 ???
      posted on 2012-09-24 23:10  Richard Wei  閱讀(1610)  評論(5)    收藏  舉報

      主站蜘蛛池模板: 狠狠色噜噜狠狠狠888米奇视频| 欧美激情综合色综合啪啪五月| 亚洲av成人免费在线| 粉嫩av蜜臀一区二区三区| 国产免费踩踏调教视频| 北流市| 国产精品国产精品国产精品| 欧美成人精品手机在线| 久久午夜夜伦鲁鲁片免费无码| 四虎在线永久免费看精品| 99福利一区二区视频| 东北妇女精品bbwbbw| 日韩精品久久不卡中文字幕| 午夜国产精品福利一二| 国产一区二区高清不卡| 国产精品大片中文字幕| 99精品日本二区留学生| 午夜激情福利一区二区| 午夜男女爽爽影院在线| 日韩av在线一区二区三区| 国产一区二区丰满熟女人妻| 国产高清在线不卡一区| 最近中文字幕国产精品| 国产成年码av片在线观看| 久久五月丁香合缴情网| 亚洲色大成网站www永久一区| 久久人人97超碰精品| 男女性杂交内射女bbwxz| 国产妇女馒头高清泬20p多| 日本久久99成人网站| av深夜免费在线观看| 于都县| 欧美z0zo人禽交另类视频| 她也色tayese在线视频| 久热色视频精品在线观看| 舞阳县| 国产精品午夜福利片国产| 成A人片亚洲日本久久| 亚洲少妇人妻无码视频| 亚洲精品色一区二区三区| 久久99精品久久久久麻豆|