簡體   English   中英

我是否可以避免對需要模板成員的類進行模板化?

[英]Can I avoid templating a class which needs to have a templated member?

我有兩個類: CFileFinderThread封裝一個工作線程,而CFileFinderCallbackForwarder將線程數據轉發到幾個可能的外部回調函數之一(具有不同的簽名)。 回調函數的類型是轉發器的模板參數。

CFileFinderCallbackForwarder<zCallBack> forwarder(zcallback);
CFileFinderThread<zCallBack> thread(forwarder);
while (thread.WaitForThread(0) != WAIT_OBJECT_0)
{
    bool eventSignaled = ::WaitForSingleObject(forwarder.getCallbackSignal(), 
                                               DEFAULT_CALLBACK_MILLIS)
                         == WAIT_OBJECT_0;
    forwarder.ExternalCallback(eventSignaled);
}

線程類保留對轉發器實例的引用,並調用轉發器中的方法以在其中存儲數據,但僅使用不以任何方式使用template參數的方法。 實際上,根據template參數不同的唯一方法是ExternalCallback

是否可以避免使用轉發器使用的回調函數類型來模板化線程類?

或有什么替代方法? 因為線程實際上根本不需要關心轉發器將如何處理其數據。

將您的轉發器類分為非通用基類和通用派生類 顯然,非通用基類應該包含所有非通用數據和操作; 派生類應包含ExecuteCallback函數。

這也使您可以使線程類也非通用。

這是一個簡化而完整的示例:

// non-generic base:
class CFileFinderCallbackForwarderBase
{
private:
    int i;
protected:
    // making the constructor protected here is just good practice:
    CFileFinderCallbackForwarderBase() {}
public:
    void SetData() { i = 0; }
};

// thread class is now non-generic
class CFileFinderThread
{
private:
    // thread class is non-generic because it only uses
    // the base class:
    CFileFinderCallbackForwarderBase* forwarder;

public: 
    CFileFinderThread(CFileFinderCallbackForwarderBase* forwarder) :
        forwarder(forwarder)
    {
    }

    void f()
    {
        forwarder->SetData();
    }
};

// derived class is generic:
template <class T>
class CFileFinderCallbackForwarder : public  CFileFinderCallbackForwarderBase
{
public:
    void ExternalCallback()
    {
        T t;
        t = 0;
    }
};

int main()
{
    CFileFinderCallbackForwarder<int> forwarder;
    CFileFinderThread thread(&forwarder);
    forwarder.ExternalCallback();
}

此技術的積極副作用可能是減少代碼膨脹。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM