天天看點

template

函數模闆

以下以取最大值的函數模闆maximum為例。此函數在編譯時會自動産生對應輸入變量的資料類型的實際代碼。

#include <iostream>
 
template <typename T>
inline const T& maximum(const T& x,const T& y)
{
   if(y > x)
      return y;
   else
      return x;
}
 
int main(void)
{
   using namespace std;
   //Calling template function
   std::cout << maximum<int>(3,7) << std::endl;         //輸出 7
   std::cout << maximum(3, 7) << std::endl;             //和上面相同
   std::cout << maximum<double>(3.0,7.0) << std::endl;  //輸出 7
   return 0;
}      

類别模闆

以下以将元件指針的操作,封裝成類别模闆ComPtr為例。

#pragma once
 
template <typename Ty>
class ComPtr
{
protected:
    Ty* m_ptr;
 
public:
 
    ComPtr()
    {
        m_ptr = NULL;
    }
 
    ComPtr(const ComPtr& rhs)
    {
        m_ptr = NULL;
        SetComPtr(rhs.m_ptr);
    }
 
    ComPtr(Ty* p)
    {
        m_ptr = NULL;
        SetComPtr(p);
    }
 
    ~ComPtr()
    {
        Release();
    }
 
    const ComPtr& operator=(const ComPtr& rhs)
    {
        SetComPtr(rhs.m_ptr);
        return *this;
    }
 
    Ty* operator=(Ty* p)
    {
        SetComPtr(p);
        return p;
    }
 
    operator Ty* ()
    {
        return m_ptr;
    }
 
    Ty* operator->()
    {
        return m_ptr;
    }
 
    operator Ty** ()
    {
        Release();
        return &m_ptr;
    }
 
    operator void** ()
    {
        Release();
        return (void**)&m_ptr;
    }
 
    bool IsEmpty()
    {
        return (m_ptr == NULL);
    }
 
    void SetComPtr(Ty* p)
    {
        Release();
 
        m_ptr = p;
        if (m_ptr)
        {
            m_ptr->AddRef();
        }
    }
 
    void Release()
    {
        if (m_ptr)
        {
            m_ptr->Release();
            m_ptr = NULL;
        }
    }
};      
  • ​​Borland​​模型(包含模闆編譯模式):​​編譯器​​​生成每個​​編譯單元​​​中遇到的所有的模闆執行個體,并存放在相應的​​目标檔案​​​中;​​連結器​​​合并相同的模闆執行個體,生成​​可執行檔案​​​。為了在每次模闆執行個體化時模闆的定義都是可見的,模闆的聲明與定義放在同一個.h檔案中。這種方法的優點是​​連結器​​​隻需要處理​​目标檔案​​​;這種方法的缺點是由于模闆執行個體被重複編譯,編譯時間被加長了,而且不能使用系統的​​連結器​​​,需重新設計​​連結器​​。
  • ​​Cfront/查詢​​模型(分離(Separation)模闆編譯模式):​​AT&T公司​​​的​​C++​​​​編譯器​​​​Cfront​​為解決模闆執行個體化問題,增加了一個模闆倉庫,用以存放模闆執行個體的代碼并可被自動維護。當生成一個​​目标檔案​​​時,​​編譯器​​​把遇到的模闆定義與目前可生成的模闆執行個體存放到模闆倉庫中。​​連結​​​時,​​連結器​​​的包裝程式(wrapper)首先調用​​編譯器​​​生成所有需要的且不在模闆倉庫中的模闆執行個體。這種方法的優點是​​編譯​​​速度得到了優化,而且可以直接使用系統的​​連結器​​​;這種方法的缺點是複雜度大大增加,更容易出錯。使用這種模型的源程式通常把模闆聲明與非内聯的模闆成員分别放在.h檔案與模闆定義檔案中,後者單獨​​編譯​​。
  • 混合(疊代)模型:​​g++​​​目前是基于​​Borland​​​模型完成模闆執行個體化。​​g++​​​未來将實作混合模型的模闆執行個體化,即​​編譯器​​​把​​編譯單元​​​中的模闆定義與遇到的目前可實作的模闆執行個體存放在相應的​​目标檔案​​​中;​​連結器​​​的包裝程式(wrapper)調用​​編譯器​​​生成所需的目前還沒有執行個體化的模闆執行個體;​​連結器​​​合并所有相同的模闆執行個體。使用這種模型的源程式通常把模闆聲明與非内聯的模闆成員分别放在.h檔案與模闆定義檔案中,後者單獨​​編譯​​。

繼續閱讀