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

Assigning C-function pointer to a member function

本文关键字:函数 成员 分配 指针      更新时间:2023-10-16

已编辑

我想将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但我得到了一个汇编

错误。。\swctext.cpp|25|error: 无法在赋值中将"void (swc::swcText::*)()"转换为"void (*)()"|

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

当你调用一个非static成员函数时,你总是将对对象的引用传递到函数中,即this指向的实体。声明为 void(*)() 的函数不带任何参数,因此与成员函数指针不兼容:无法分配它们。您需要以某种方式掌握其他对象。当然,最简单的方法是只使用std::function<void()>并将函数std::bind()到对象(不需要使用 lambda):

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() 往往会完成很多额外的技巧,并且可以更有效地使用,尤其是在将带有内联调用运算符的函数对象传递给它们时(除了更加灵活之外)。