我有一个函数Foo和一个类CDelegate。
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);
我想通过调用静态对象的()运算符来调用Foo
:CSpi1::m_Delegate();
我在(*m_ref_Wrapper)(0);
收到例外
语法有问题吗?我不太确定我尝试做的事情是否可行。我有一个有效的解决方案,其中CDelegate
的构造函数不接受函数指针的const引用,而是函数指针本身。然后我可以在()运算符中调用该函数而不会出现问题。我想使用const引用,因为函数指针调用无法优化,我希望通过const引用调用可以因为所有内容都应该在编译时知道。
答案 0 :(得分:1)
你持有对函数指针的引用(并且指针是一个临时的,它在你使用它时被破坏了,所以事情出现了严重的错误。)
尝试将typedef更改为函数类型:
typedef void typeFct(void*);
...
const typeFct & m_ref_Wrapper;
然后使用现有的代码,你最终会得到一个函数的引用,你会没事的。或者您可以存储指向函数的指针 - const typeFct *
。
在任何一种情况下,电话都可以是m_ref_Wrapper(0)
。
一般来说,我更喜欢使用typedef函数类型而不是指向指针或引用,只是因为语法不那么难看。
答案 1 :(得分: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;
};