typedef void(__ thishisall * 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:'type cast':无法从'void(__ thiscall ClassB :: *)(void)'转换为'LPVOIDPROC'?我不想将LPVOIDPROC签名仅限制为ClassB。这应该是任何类,引用的proc不应该是静态的。
答案 0 :(得分:3)
解决方法:
typedef void (* CLASSPROC) (void *);
template<class T, void (T::*proc)()>
void class_proc(void * ptr)
{
(static_cast<T*>(ptr)->*proc)();
}
class ClassA
{
CLASSPROC m_pProc;
void * m_pInstance;
public:
void SetProc(void *pInstance, CLASSPROC pProc) {
m_pInstance = pInstance;
m_pProc = pProc;
}
void OnSomeEvent() { m_pProc(m_pInstance); }
};
class ClassB
{
ClassA* pCA;
void Proc() { /* ... */ }
void Init()
{
// Assume pCA != NULL
pCA->SetProc(this, class_proc<ClassB, &ClassB::Proc>);
}
};
答案 1 :(得分:2)
我推荐你link。您的类型LPVOIDPROC
是指向函数的指针,它与指向成员函数的指针不同。当您尝试转换ClassB::Proc
时,您正在尝试将指针转换为成员函数,这是一种无效的操作。
你应该看看boost::function
,它提供你正在寻找的东西。或者,如果您不想求助,可以使用仿函数来封装函数。例如:
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() }
答案 2 :(得分:0)
非静态方法需要一个'this'指针,没有'this'指针你无法调用它,因此将它转换为C函数指针是没有意义的。
考虑制作一个具有
的简单类(让我们称之为X)不是将函数指针传递给类A,而是创建一个X实例(其数据库为ClassB填充)并将其传递给类A. 而不是调用函数指针类A应该调用x()。
甚至可以使用模板编写X类,因此如果您有多个类的情况,则必须只编写一次。
我认为在C#中,使用代理可以更清晰,但我将其留给C#和.Net专家。
答案 3 :(得分:0)
永远不会转换函数指针。最终可能会出现堆栈损坏。不要这样做。
不要将指针传递给非静态成员函数。它们使用不同的调用约定并且不兼容。
在您的情况下,将“Proc()”设为静态可能会解决问题。
答案 4 :(得分:-1)
您需要将Proc
方法作为静态方法。