[英]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.