将C函数指针分配给成员函数

时间:2014-01-05 04:39:58

标签: c++ function-pointers

被修改

我想将class X的C函数指针绑定到class Y的另一个成员函数。

他们的实现看起来像这样

//The class w/c has the C-function pointer
class XString
{
public:
    ...
private:
    void (*eventOnChange)();

    friend class swc::swcText;
};

//The class w/c I want to assign/bind the XString::eventOnChange;
class swcText
{
public:

    swcText()
    {
        //how can I do this
        text.eventOnChange = &swcText::computeTextSize;
    }
    ...

    XString text;
private:

    void computeTextSize();
};

我想实现text.evenOnChange = this->computeTextSize但我得到了一个汇编

error ..\swctext.cpp|25|error: cannot convert 'void (swc::swcText::*)()' to 'void (*)()' in assignment|

我知道我可以使用std::function<void()> eventOnChange执行此操作并分配lambda函数,但如何在C风格的函数指针中执行此操作?

1 个答案:

答案 0 :(得分:3)

当您调用非static成员函数时,您始终将对象的引用传递给函数,即this指向的实体。声明为void(*)()的函数不接受任何参数,因此与成员函数指针不兼容:无法分配它们。你需要以某种方式获得额外的对象。当然,最简单的方法是将std::function<void()>std::bind()函数用于对象(不需要使用lambdas):

std:function<void()> f;
f = std::bind(&Y::computeTextSize, this);

如果你坚持不想使用类似的东西,你可以建立类似于std::function<void()>std::bind()的功能,这些功能非常有限:

class function
{
    void* object;
    void (*fun)(void*);
public:
    function(): object(), fun() {}
    function(void* o, void(*f)(void*)): object(o), fun(f) {}
    void operator()() const { if (object) (this->fun)(object); }
};

template <typename T, void (T::*member)()>
void call(void* object) {
    (static_cast<T*>(object)->*member)();
}
template <typename T, void (T::*member)()>
function bind(T* object) {
    return function(object, &call<T, member>);
}

您可以使用上述功能,例如

text.eventOnChange = bind<swcText, &swcText::computeTextSize>(this);

但请注意,std::function<...>std::bind()往往会带来一些额外的技巧,并且可以更有效地使用,尤其是在将具有内联调用操作符的函数对象传递给它们时(除了很多更灵活。)