2013-01-20 50 views
0

我正在編寫一個多線程方案的包裝。它應該像定時器一樣運行。接收functor作爲參數的最常用方法是什麼?

我有一個特殊的類(clock),它實現了一個名爲tick的函數,該函數應該被傳遞給構造函數。我如何將C++樣式函數(myClass :: myfunction,而不是C約定)描述爲方法或構造函數的參數?

任何人都會友善地向我展示這種構造函數的聲明嗎?

clock myInstance(otherClass::aMethod) 
myInstance.tick(); // Should call otherClass::aMethod 
myInstance.tick(); 

C++ 11和Bind有幫助嗎?

+0

你問的是如何傳遞一個C++類的* non * -static *成員函數作爲參數? – WhozCraig

+0

@WhozCraig,是的,但它不會是虛擬的。如果我只能使用靜態,你能解釋一下嗎? – Mikhail

+0

什麼對象應該調用'otherClass :: aMethod'? – Mankarse

回答

5

您可以調用一個類的靜態成員函數或一個對象的非靜態成員函數。非靜態成員函數需要具有對象的上下文(this指針)。

下面是如何使用函數和綁定調用成員函數的簡化示例。

#include <functional> 

class clock 
{ 
public: 
    clock(const std::function<void()>& tocall) : m_tocall(tocall) {} 
    void tick() {m_tocall();} 

private: 
    std::function<void()> m_tocall; 
}; 

class otherclass 
{ 
public: 
    void aMethod() {} 
}; 

int main(int argc, char *argv[]) 
{ 
    otherclass A; 
    clock c(std::bind(&otherclass::aMethod, &A)); 

    c.tick(); // Will end up calling aMethod() of object A 
} 
+0

使用模板參數而不是std :: function會給你一個較少的間接級別,並且會加速調用。請參閱http://stackoverflow.com/questions/12446596/c-boost-bind-performance/12446751 –

+1

@ slavik262謝謝。我學到了新東西:-)如果這不是性能瓶頸,我會選擇更易讀的形式。由於成員需要'std :: function',除非你爲模板化課程,我不確定是否有任何速度差異? –

+0

'std :: bind'不會返回一個'std :: function'對象 - ''bind'的返回值可以被'function'封裝*,這會造成一些開銷(參見https:// github的.com/slavik262 /功能間接)。但是,如果這不是關鍵性能問題,請隨意使用任何您認爲更具可讀性的內容。 –

1

您無需爲此使用std::function。你需要有兩個指針:一個是類對象,另一個是該類的方法。簡單來說,你需要使它能夠做到:

CallNonVirtual(pClassPtr, pFuncAddr); 

也因此,你需要兩個參數,這樣就可以實際上這樣稱呼它:

(pClassPtr->*pFuncAddr)(); // Assuming no parameter 

對於這一點,你可以這樣做:

class Clock 
{ 
    COtherClass* pClassPtr; 

    /// Typedef simplifies 
    typedef void (COtherClass::*TargetFuncType)(); 
    TargetFuncType pFuncAddr; 

public: 
    Clock(COtherClass* pOther, TargetFuncType pFunc) : 
      pClassPtr(pOther), pFuncAddr(pFunc) 
    { 
    } 

    void tick() 
    { 
     (pClassPtr->*pFuncAddr)(); 
    } 
};  

並撥打電話:

int main() 
{ 
    COtherClass Obj; 
    Clock theClock(&Obj, &COtherClass::TheNonStatic); 

    theClock.tick(); 
} 
相關問題