我想基於一個使用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