C++如何将类成员函数作为回调传给接收普通函数指针的Worker类
问题解决方法
报错原因
Worker定义的回调类型callFunct是无上下文的普通C函数指针,而类的非静态成员函数存在隐含的this指针作为第一个入参,二者类型完全不兼容,因此无法直接转换赋值。
可行实现方案
方案1:使用std::function包装回调(最推荐)
修改Worker的回调类型为std::function<int(int)>,支持绑定带实例上下文的可调用对象,无需牺牲类成员访问能力:
// 修改后的Worker代码 #include <functional> class Worker { public: using callFunct = std::function<int(int)>; Worker(callFunct callback = nullptr); ~Worker() = default; private: callFunct m_callback = nullptr; }; Worker::Worker(callFunct callback) : m_callback(std::move(callback)) { }
// 修改后的myClass代码 class myClass { public: myClass(); ~myClass() = default; private: int myCallback(int x); Worker m_worker; }; // 构造函数中绑定实例与成员函数,可用lambda或std::bind实现 myClass::myClass() : m_worker([this](int x) { return myCallback(x); }) { }
方案2:将回调设为静态成员函数(无需修改Worker代码)
静态成员函数没有隐含的this参数,类型匹配普通函数指针,缺点是静态函数内无法直接访问类的非静态成员:
class myClass { public: myClass(); ~myClass() = default; private: // 改为静态成员函数 static int myCallback(int x); Worker m_worker {&myClass::myCallback}; };
方案3:增加上下文指针适配(兼容原生C风格回调设计)
如果不能修改原回调的函数指针类型,可调整回调签名增加void*类型的上下文参数传递实例指针:
// 修改后的Worker代码 class Worker { public: typedef int (*callFunct)(int, void* user_data); Worker(callFunct callback = nullptr, void* user_data = nullptr); ~Worker() = default; private: callFunct m_callback = nullptr; void* m_user_data = nullptr; }; Worker::Worker(callFunct callback, void* user_data) : m_callback(callback), m_user_data(user_data) { } // Worker内部触发回调时的调用逻辑: // if (m_callback) m_callback(参数值, m_user_data);
// 修改后的myClass代码 class myClass { public: myClass() : m_worker(&myClass::staticCallback, this) {} ~myClass() = default; private: static int staticCallback(int x, void* user_data) { // 上下文指针强转为myClass实例即可访问非静态成员 auto* self = static_cast<myClass*>(user_data); return self->myCallback(x); } int myCallback(int x); Worker m_worker; };
内容的提问来源于stack exchange,提问作者Sebastian Green
相关产品推荐
相关产品推荐

