2011-06-30 54 views
1

我有一個函數Foo和一個CDelegate類。函數指針的const引用

typedef void (*typeFctPtr)(void*); 


void Foo(void* dummy) 
{ 
    cout << "Foo\n"; 
} 


class CDelegate 
{ 
    public: 

    CDelegate (const typeFctPtr& f_ref_Wrapper, void* f_pvSubscriber) 
    : m_ref_Wrapper(f_ref_Wrapper), m_pvSubscriber(f_pvSubscriber) 
    { 
    } 

    inline void operator()() const 
    { 
    (*m_ref_Wrapper)(0); 
    } 

    inline void operator=(const CInterruptDelegate& D) 
    { 
    } 

private: 
    void* m_pvSubscriber; 
    const typeFctPtr& m_ref_Wrapper; 
}; 

第二類有一個靜態成員static CDelegate m_Delegate;我初始化使用這樣的構造:

CInterruptDelegate CSpi1::m_Delegate(FreeFunction, 0); 

我想打電話給我的靜態對象的()操作符來調用FooCSpi1::m_Delegate();

我在(*m_ref_Wrapper)(0); 得到一個異常語法有問題嗎?我不太確定我所嘗試做的事情是否可能。我有一個工作解決方案,CDelegate的構造函數不接受函數指針的const引用,而是函數指針本身。然後,我可以在()運算符中調用該函數而不會出現問題。我想使用const引用,因爲函數指針調用不能被優化,我希望通過const引用的調用可以,因爲在編譯時應該知道所有東西。

+0

你有沒有打過電話只是'm_ref_Wrapper(0);'? – iammilind

+0

如果優化器能夠使用引用或指針移除間接調用,我會感到驚訝。但間接呼叫實際上並不昂貴。 –

+0

@Cat Plus Plus,我使用這種機制在嵌入式系統中進行中斷處理。 boost :: function做我需要的一切,但是有點慢。另外,軟件正在將參數作爲函數指針。我想通過使用const引用來優化...至少嘗試:) – Mirco

回答

1

你正在持有對函數指針的引用(並且指針是臨時的,在你使用它的時候已經被破壞了,所以事情發生嚴重錯誤)。

試着改變你的typedef是一個函數類型:

typedef void typeFct(void*); 
... 
const typeFct & m_ref_Wrapper; 

然後與現有的代碼,你將與一個函數的引用結束了,你會沒事的。或者你可以存儲一個指向函數的指針 - const typeFct *

無論哪種情況,通話只能是m_ref_Wrapper(0)

一般來說,我更喜歡typedef函數類型而不是指針或引用,如果僅僅因爲語法不那麼醜陋。

+0

謝謝,我可以編譯這個,我沒有得到任何運行計時器錯誤。但是我得到警告'警告C4180:應用於函數類型的限定符沒有任何意義;忽略'這些行:'CDelegate(const typeFct&f_ref_Wrapper,void * f_pvSubscriber)'和'const typeFct&m_ref_Wrapper;' – Mirco

+0

@Mirco啊是的,我的錯誤。不應該有一個const適用於typeFct的任何地方。 const對於數據來說很好,對函數沒有意義。 –

1

我認爲這個問題是成員的聲明:

const typeFctPtr& m_ref_Wrapper; 

相反,嘗試刪除&

const typeFctPtr m_ref_Wrapper; 

的引用必須引用另一個現有對象。在這種情況下,它會在調用構造函數時引用創建的臨時對象以保存對指針的引用。

雖然我們在這,但我建議您應該從構造函數中刪除引用。原因是當你使用標量:s時沒有任何好處。

使代碼更具可讀性的另一件事是,如果要鍵入該函數的類型,而不是指向該函數的指針。這樣,很明顯你會傳遞一個指針。

以下是總結的變化的簡化版本我上面建議:

typedef void (typeFct)(void*); 

class CDelegate 
{ 
    public: 

    CDelegate (typeFct * f_Wrapper, void* f_pvSubscriber) 
    : m_ref_Wrapper(f_Wrapper), m_pvSubscriber(f_pvSubscriber) 
    { 
    } 

    inline void operator()() const 
    { 
    (*m_ref_Wrapper)(0); 
    } 

private: 
    void* m_pvSubscriber; 
    typeFct * m_ref_Wrapper; 
}; 
+0

+1似乎只是公平的 –

+0

謝謝!順便說一句,我從你的帖子中學到了一些新東西,我不知道你可以參考一個函數。 – Lindydancer

+0

@Lindydancer,我認爲這是我的工作解決方案,使用函數指針而不是使用一個引用 - 與typedef的區別。我會記住這一點,並開始在未來的typedef函數的類型:)不幸的是,我不能+1(仍然<15)..感謝您的幫助 – Mirco

相關問題