我想基于一个使用boost.threadpool抽象线程池的公用类来实现一些类。我已经得到了一些可行的方法(在osx 10.7.2上的Xcode中),但我真的不确定它的好设计,或者它甚至是安全的(主要是因为我在线阅读了关于使用虚拟成员函数与模板)。我正在寻找一些风格建议,以实现像这样的最佳方式。我学习,我走在这里让我认识了很多,这将是“不好的形式” ......模板化虚拟功能的C++设计帮助
我有所谓的“工作队列”这样一个基类:
template <typename T>
class Workqueue{
private:
pool *pThreadPool;
public:
Workqueue (int);
void Start (T);
void Schedule (T);
virtual bool Process(T) {return true;}
};
template <typename T> Workqueue<T>::Workqueue(int thread_count){
pThreadPool = new pool(thread_count);
}
template <typename T> void Workqueue<T>::Start(T data){
pThreadPool->schedule(boost::bind(&Workqueue::Process,this, data));
pThreadPool->wait();
}
template <typename T> void Workqueue<T>::Schedule(T data){
pThreadPool->schedule(boost::bind(&Workqueue::Process,this, data));
}
然后我定义基于这个类这样的新服务:
struct Service1Data{
string item_data;
};
class MyService : public Workqueue<Service1Data> {
public:
MyService (int);
bool Process (Service1Data);
};
MyService::MyService(int workers) : Workqueue<Service1Data>(workers) {}
bool MyService::Process(Service1Data service_data){
cout << "in process (" << service_data.item_data << ")" << endl;
return true;
}
(我已经尽可能多的代码,以保持它的简单去除,如图所示会永远运行下去,因为它不断地提出新的工作)。我使用这样的服务:
MyService *service1 = new MyService(5);
Service1Data x;
x.item_data = "testing";
service1->Start(x);
// will wait until no more work.
delete service1;
所以我的具体问题:
首先(和请温柔...)是这个坏形式,是有一个更好的方法来做到这一点? (以及为什么?)
其次 - 这是甚至安全的虚拟/模板问题?我在某个地方读到,如果课堂本身是模板化的,我认为我理解基本的问题 - 但实际上不确定具体细节。
第三 - 基准workqueue类需要在'h'文件中具有类定义的成员定义以便链接。不知道为什么会这样 - 我想这是一个与虚拟/模板问题有关的链接器问题,所以让我感到紧张。
所有帮助感激地接受..
克里斯
“如果类本身被模板化了,应该是安全的” - 正确,它只是'template虚拟空间f(T);'只是不能解决问题。如果您有模板类,则函数的参数类型已经确定,并且只需要vtable中的一个条目。 –
Xeo
2012-01-10 17:52:04
谢谢 - 大概是因为类模板将在编译时解析?那是对的吗? – 2012-01-10 17:58:41
*任何*模板将在编译时解析 - 这是它们的本质。你只会遇到真正的虚拟函数模板的问题,因为对于函数可能调用的每个参数类型都需要不同的vtable条目,这是不可能的。 – Xeo 2012-01-10 18:00:30