2009-10-15 30 views
2

我有一個工作線程,它包含一個'線程操作'列表,並通過它們作爲一個工作時間。重新解釋成員函數指針是個好主意嗎?

template <class T> class ThreadAction 
{ 
public: 

    typedef void (T::*action)(); 

    ThreadAction(T* t, action f) : 
    func(f),obj(t) {} 
    void operator()() { (obj->*func)(); } 

    void (T::*func)(); 
    T* obj; 

}; 

它通常被稱爲像這樣

myActionThread->addAction(
    new ThreadAction<TheirClass>(this, &TheirClass::enable) 
); 

這工作得很好,直到

void TheirClass::enable() 

改爲

bool TheirClass::enable() 

可悲的是,我們不能再因爲改回來其他的東西需要新的東西格式,(和重載不能單獨返回類型不同)。

我曾嘗試

myActionThread->addAction( 
    new ThreadAction<TheirClass>(this, 
     reinterpret_cast<void(TheirClass::*)>(&TheirClass::enable) 
    ) 
); 

這似乎工作得很好,但我不肯定,重新詮釋一個函數指針像這樣的「定義」的行爲,可有人請指教?

回答

9

這絕對是而不是支持的行爲,並可能導致您的程序崩潰。

基本上,你需要爲TheirClass::enable()做一個包裝,它將具有正確的返回類型。一個簡單的一行就足夠了:

public: 
    void enableWrapper() { enable(); }; 

然後調用:

myActionThread->addAction(
    new ThreadAction<TheirClass>(this, &TheirClass::enableWrapper) 
); 

如果您不能直接修改TheirClass,然後創建一個實現了包裝簡單的子類或輔助類。

+0

重新解釋成員函數指針特別糟糕,因爲它們的大小可能因類而異:http://blogs.msdn.com/oldnewthing/archive/2004/02/09/70002.aspx – bdonlan 2009-11-03 03:56:11

2

Err,據我所知,你是從一個返回bool返回void的方法的方法投射?

這可能是危險的,這取決於使用中的調用/返回約定。您可能會可能忘記彈出返回值 - 或者用返回值覆蓋寄存器的值。

+0

+1關於覆蓋的好處一個帶有返回值的寄存器。 – 2009-10-15 15:07:25

2

不是一個好主意。考慮添加額外的模板參數返回類型:

template <class T, typename RetType> class ThreadAction 
{ 
public: 
typedef RetType (T::*action)(); 
ThreadAction(T* t, action f) : 
    func(f),obj(t) {} 

RetType operator()() { return (obj->*func)(); } 
RetType (T::*func)(); 
T* obj; 
}; 

這是return void的應用程序。

+1

在typedef中,void需要更改爲RetType – Sumant 2009-11-02 05:11:35

+0

修正了它,謝謝! – 2009-11-03 03:43:54

1

我通常會發現,當問題的形式是「是_______一個好主意嗎?」答案几乎總是「不!」

這可能是沒有上下文的情況下。

+0

SO允許你回答你自己的問題....:-) – 2009-10-15 15:45:04