atl中常見的模板使用手法

來源:互聯網
上載者:User

1、傳入基類,繼承實現
在設計com介面時,經常會遇到這樣的情況:設計一個基底介面,其他多個介面繼承該介面。一個典型的例子是IUnknown介面,所有的com介面必須從IUnknown介面繼承,而這些介面的實現都是相同的,我們不可能為每一個com介面寫一個IUnknown介面的實現。IUnknown介面的實現比較複雜,分布在幾個類中(可參考《深入解析atl》)。比較直觀的一個例子是IDispatch介面的實現,通常需要實現IDispatch介面的類都從IDispatchImpl繼承。這個結構是這樣的:

class ATL_NO_VTABLE Cbbb :
 public IDispatchImpl<Ibbb, &IID_Ibbb, &LIBID_AAAALib>

template <class T, ...>
class ATL_NO_VTABLE IDispatchImpl : public T
               
這樣,每個需要實現IDispatch介面的類都只需要從IDispatchImpl繼承即可。
IDispatchImpl的做法其實相當簡單,僅僅是引入了一個實作類別而已。
另一種常見的情況是分離介面和實現。比如有以下的介面繼承結構:
interface IBase
{
    virtual void A()=0;
};
interface IDerive1 : public IBase
{
    virtual void D1()=0;
};
interface IDerive2 : public IBase
{
    virtual void D2()=0;
};
IBase對應的實作類別如下:
class CBase : public IBase
{
    virtual void A(){...}
};
這裡假設有一個類CDerive1需要繼承介面IDerive1和實作類別CBase,如果直接從兩個類繼承,象這樣:
class CDerive1 : public CBase,public IDerive1
{
public:
    void D1(){}
};
當使用CDerive1類時,編譯器會抱怨模稜兩可。很自然的,考慮到用虛擬繼承解決:
interface IDerive1 : virtual public IBase
{
    virtual void D1()=0;
};
class CBase : virtual public IBase
{

public:
    virtual void A(){...}
};
class CDerive1 : public CBase,public IDerive1
{
public:
    void D1(){}
};
一切看起來都很完美,virtual繼承解決了模稜兩可問題。但是虛擬繼承是很多產生複雜性問題的根源,難以擴充和維護.
看來我們還是只有老老實實加一個中介層吧。最終解決方案如下:

template<typename TBase>
class CBase : public TBase
{
public:
    virtual void A(){...}
};
class CDerive1 : public CBase<IDerive1>
{
public:
    void D1(){}
};

2、傳入子類
在atl中,有大量的以下用法:
template<typename T>
class CB
{
public:
    void Fun1()
    {
        T* pT = static_cast<T*>(this);
        pT->FunD(); //調用T的函數
    }
};
這裡傳進來的是CB的子類
class CD : public CB<CD>
{
public:
    void FunD(){...}
};

這種技術實際上有點象虛函數.

以上語句T* pT = static_cast<T*>(this)之所以能編譯通過是因為模板類CB在編譯期間已被執行個體化為CB<CD>,編譯器已經知道T就是CD,而CD繼承自CB,所以從CB向CD轉型是安全的.這種手法的一個好處是不需要一個T類型的對象,直接可以使用this指標安全轉型.其2,避免了虛函數調用的開銷,雖然虛函數的開銷是很小的,單繼承情況下幾乎可以忽略不計,但是虛函數的存在不利於編譯器的最佳化,而且static和inline虛函數也要出問題.

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.