2010-02-18 74 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()”静态可以解决问题。