2010-02-18 75 views
2

typedef void(__thiscall * LPVOIDPROC)(void);轉換方法簽名

class ClassA 
{ 
    LPVOIDPROC m_pProc; 

    void SetProc(LPVOIDPROC pProc) { m_pProc = pProc; } 

    void OnSomeEvent() { m_pProc(); } 
} 

class ClassB 
{ 
    ClassA* pCA; 

    void Proc() { /* ... */ } 

    void Init() 
    { 
    // Assume pCA != NULL 
    pCA->Set((LPVOIDPROC)&ClassB::Proc); // error C2440 
    } 
} 

如何擺脫這種錯誤C2440的: '類型轉換':無法從 '無效(ClassB的__thiscall :: *)(無效)' 到 'LPVOIDPROC' 轉換?我不想僅將LPVOIDPROC簽名限制爲ClassB。這應該是任何類和引用的proc不應該是靜態的。

+0

如果該方法不是靜態的 - 您如何將類實例傳遞給ClassA? – Mark 2010-02-18 11:47:19

回答

3

解決方法:

​​
2

我向你推薦這個link。您的類型LPVOIDPROC指針函數,它與指針指向成員函數不同。當您嘗試投射ClassB::Proc時,您試圖將指針指向成員函數轉換爲無效操作。

你應該看看boost::function,它提供了你正在尋找的東西。或者你可以使用函數來封裝你的函數,如果你不想求助於boost。例如:

struct VoidProcFunctor { 
    virtual void call() = 0; 
}; 

class ClassB; 
struct BProcFunctor : VoidProcFunctor { 
    BProcFunctor(ClassB* b) : b_(b) {} 
    void call(); 
private: 
    ClassB* b_;   
} 

class ClassA 
{ 
public: 
    VoidProcFunctor* m_pProc; 

    void SetProc(VoidProcFunctor* pProc) { m_pProc = pProc; } 

    void OnSomeEvent() { m_pProc->call(); } 
}; 

class ClassB 
{ 
    ClassA* pCA; 

    void Proc() { /* ... */ } 

    void Init() 
    { 
     // Assume pCA != NULL 
     // warning! this is not the best design possible 
     BProcFunctor* bproc = new BProcFunctor(this); 
     pCA->SetProc(bproc); 
    } 
}; 

void BProcFunctor::call() { b_->proc() } 
0

非靜態方法需要this指針,沒有this指針,你不能把它的,所以它是沒有意義的它轉換爲C函數指針。

考慮做一個簡單的類(姑且稱之爲X)擁有

  • 是指ClassB的實例
  • 一個()操作(雖然我更喜歡有明確的名稱的方法)調用ClassB的數據成員:: Proc使用ClassB實例作爲此指針。

不是傳遞函數指針到A級,使X(其數據成員到ClassB的填充)的一個實例,它傳遞給A級 而不是調用一個函數指針類A應該調用x的( )。

X類甚至可以使用模板編寫,所以如果你有多於一個類的這種情況,你只能寫一次。

我認爲在C#中可以使用委託來完成更清潔的工作,但我將其留給了C#和.Net專家。

-1

你需要你的Proc方法是一個靜態方法。

+0

OP說*這應該是任何類和引用的proc應該不是靜態**。* – 2010-02-18 16:03:07

0
  1. 從不轉換函數指針。你最終可能會發生堆棧損壞。不要這樣做。

  2. 不要將指針傳遞給非靜態成員函數。他們使用不同的調用約定並且不兼容。

  3. 在你的情況下,使「Proc()」靜態可以解決問題。