c++类的成员函数作回调函数为啥要声明为static的

7 篇文章 0 订阅

简单说明

C++的类成员函数不能像普通函数那样用于回调,因为每个成员函数都需要有一个对象实例去调用它。

把成员函数作为回调函数,可以把该成员函数声明为静态成员函数,但这样做有一个缺点,就是会破坏类的结构性,因为静态成员函数只能访问该类的静态成员变量和静态成员函数,不能访问非静态的,要解决这个问题,需要把对象实例的指针或引用做为参数传给它。

因为类的成员函数需要隐含的this指针 而回调函数没有办法提供

代码示例一

//头文件

//声明一个函数指针类型,
typedef bool(*CallbackFunc )(void*pThis,double num);

Class A
{
	void FuncA()
	{
		m_callBackFunc(m_Ptr,num_A);
	}
	void SetCallBack(CallbackFunc callback,void *pthis)
	{
		m_callBackFunc = callback;
		m_Ptr = pthis;
	}
	CallbackFunc  m_callBackFunc;
	void* m_Ptr;
	int num_A;
}

Class B
{
	//注意参数要匹配前面声明的函数指针类型,且声明为静态
	static bool FuncB(void *pVoid,double tmpNum)
	{
		print<<pVoid->m_num;
		m_num = tmpNum;
		print<<pVoid->m_num;
	}
public:
	int m_num;
}

//调用
main()
{
	A a;
	B b;
	b.m_num = 2.0;
	a.SetCallBack(FuncB,&b);
	a.FuncA();//实现了类A调用了b的函数,并把a的成员值传给了b改变了b成员的值
}

这种情况也适用于B包含A的情况,即B里面有A的对象或对象指针,就可以实现b调用a进行一系列操作然后把a的值传回来给b;如下所示

代码示例二

//头文件
typedef bool(*CallbackFunc )(void*pThis,int num);//声明一个函数指针
Class A
{
	void FuncA()
	{
		m_callBackFunc(m_Ptr,num_A);
	}
	void SetCallBack(CallbackFunc callback,void *pthis)
	{
		m_callBackFunc = callback;
		m_Ptr = pthis;
	}
	CallbackFunc  m_callBackFunc;
	void* m_Ptr;
	int num_A;
}

Class B
{
	static bool FuncB(void *pVoid,int tmpNum)
	{
		print<<pVoid->m_num;
		m_num = tmpNum;
		print<<pVoid->m_num;
	}
	void Run()
	{
		m_a.SetCallBack(FuncB,this);
		m_a.FuncA();
	}
public:
	A m_a;
	int m_num;
}

//调用
main()
{
	B b;
	b.m_num = 2;
	b.Run();
}
C++ 中,如果要将成员函数回调函数传递给其他函数,需要使用静态成员函数或者全局函数为中间层,将回调函数传递给成员函数。这是因为成员函数在编译时会隐式地添加一个 `this` 指针为第一个参数,而回调函数通常不需要这个指针。 以下是一个示例代码,其中 `register_callback` 函数需要传递一个回调函数 `cb`,并将其保存到成员变量 `m_cb` 中: ```c++ #include <functional> class MyClass { public: void register_callback(std::function<void()> cb) { m_cb = cb; } static void static_callback(void* obj) { MyClass* self = static_cast<MyClass*>(obj); self->member_callback(); } private: void member_callback() { // do something } std::function<void()> m_cb; }; int main() { MyClass obj; // register callback using static member function obj.register_callback(std::bind(&MyClass::static_callback, &obj, std::placeholders::_1)); return 0; } ``` 在上面的示例代码中,`static_callback` 是一个静态成员函数,接收一个 `void*` 型的参数,将其转换为 `MyClass` 的指针,并调用 `member_callback` 成员函数。在 `main` 函数中,使用 `std::bind` 将 `static_callback` 和 `MyClass` 对象的地址绑定起来,然后传递给 `register_callback` 函数。 如果编译时出现非法指针转换的错误,可能是因为型转换不正确或者回调函数的参数不匹配。可以检查一下回调函数的参数型和数量,以及型转换是否正确。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值