我可以避免模仿需要模板化成员的类吗?

时间:2015-03-12 17:55:47

标签: c++ templates

我有两个类: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);
}

线程类保留对转发器实例的引用,并调用转发器中的方法以将数据存储在其中 - 但只有方法不以任何方式使用模板参数。唯一取决于模板参数的方法是ExternalCallback

是否可以避免使用转发器使用的回调函数的类型来模拟线程类?

或者替代方案是什么?因为线程真的不应该关心转发器将对其数据做什么。

1 个答案:

答案 0 :(得分:0)

将您的转发器类划分为非泛型基类和通用派生类。显然,非通用基类应包含所有非通用数据和操作;派生类应包含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();
}

这种技术的积极副作用可能是减少代码膨胀。