C++ 简单实现信号槽

这篇博客详细介绍了如何使用C++实现信号与槽机制,包括固定参数、可变参数以及不定数量和类型的参数。通过示例展示了如何创建信号、绑定函数、触发信号以及执行回调函数,适用于事件驱动编程和类间通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理:保存函数绑定类的函数指针,进行回调。

1.信号参数为指定个数,指定类型


#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;


class SlotBase
{
public:
	virtual void Exec(int param1) = 0;
	virtual ~SlotBase() {}
};

template<class T>
class Slot :public SlotBase
{
	typedef void (T::*Func)(int);
public:
	Slot(T* pOjb, Func func)
	{
		m_func = func;
		m_pSlotBase = pOjb;
	}

	void Exec(int param1)
	{
		(m_pSlotBase->*m_func)(param1);
	}
private:
	T* m_pSlotBase = NULL;
	Func m_func;
};

class Signal
{
public:
	template<class T>
	void Bind(T* obj, void (T::*func)(int))
	{
		m_pSlotSet.push_back(new Slot<T>(obj, func));
	}

	void operator()(int param1)
	{
		for (int i = 0; i < (int)m_pSlotSet.size(); i++)
		{
			m_pSlotSet[i]->Exec(param1);
		}
	}
private:
	vector< SlotBase* > m_pSlotSet;
};


class TestFunc1
{
public:
	void FunOfA(int param)
	{
		cout << __FUNCTION__ << " " << param << endl;
	}
};


class TestSignal
{
public:
	TestSignal()
	{

	}
	void emit(int value)
	{
		ValueChanged(value);
	}
public:
	Signal ValueChanged;
};

#define Connect(sender,signal,receiver,method)((sender)->signal.Bind(receiver,method));
int main()
{
	TestFunc1* pFunc1 = new TestFunc1;
	TestSignal* pSinal1 = new TestSignal();
	Connect(pSinal1, ValueChanged, pFunc1, &TestFunc1::FunOfA);

	pSinal1->emit(1);
	delete pFunc1;
	delete pSinal1;

	getchar();
	return 0;

}

2.信号参数为指定个数,不定类


#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;


template<class T>
class SlotBase
{
public:
	virtual void Exec(T param1) = 0;
	virtual ~SlotBase() {}
};

template<class T, class T1>
class Slot :public SlotBase<T1>
{
	typedef void (T::*Func)(T1);
public:
	Slot(T* pOjb, Func func)
	{
		m_func = func;
		m_pSlotBase = pOjb;
	}

	void Exec(T1 param1)
	{
		(m_pSlotBase->*m_func)(param1);
	}
private:
	T* m_pSlotBase = NULL;
	Func m_func;
};

template <class T1>
class Signal
{
public:
	template<class T>
	void Bind(T* obj, void (T::*func)(T1))
	{
		m_pSlotSet.push_back(new Slot<T, T1>(obj, func));
	}

	void operator()(T1 param1)
	{
		for (int i = 0; i < (int)m_pSlotSet.size(); i++)
		{
			m_pSlotSet[i]->Exec(param1);
		}
	}
private:
	vector< SlotBase<T1>* > m_pSlotSet;
};


class TestFunc1
{
public:
	void FunOfA(int param)
	{
		cout << __FUNCTION__ << " " << param << endl;
	}
};

class TestFunc2
{
public:
	void FuncOfB(std::string param)
	{
		cout << __FUNCTION__ << " " << param.c_str() << endl;
	}
};

template<class T1>
class TestSignal
{
public:
	TestSignal()
	{

	}
	void emit(T1 value)
	{
		ValueChanged(value);
	}
public:
	Signal<T1> ValueChanged;
};

#define Connect(sender,signal,receiver,method)((sender)->signal.Bind(receiver,method));
int main()
{
	TestFunc1* pFunc1 = new TestFunc1;
	TestFunc2* pFunc2 = new TestFunc2;
	TestSignal<int>* pSinal1 = new TestSignal<int>();
	TestSignal<std::string>* pSinal2 = new TestSignal<std::string>();

	Connect(pSinal1, ValueChanged, pFunc1, &TestFunc1::FunOfA);
	Connect(pSinal2, ValueChanged, pFunc2, &TestFunc2::FuncOfB);

	pSinal1->emit(1);
	pSinal2->emit("hahhaha");

	delete pFunc1;
	delete pFunc2;
	delete pSinal2;
	delete pSinal1;

	getchar();
	return 0;

}

3.信号参数为指定不定个数,不定类型


#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;


template< class ...Args>
class SlotBase
{
public:
	virtual void Exec(Args...args) = 0;
	virtual ~SlotBase() {}
};

template<class T, class ...Args>
class Slot :public SlotBase<Args...>
{
	typedef void (T::*Func)(Args...);
public:
	Slot(T* pOjb, Func func)
	{
		m_func = func;
		m_pSlotBase = pOjb;
	}

	void Exec(Args...args)
	{
		(m_pSlotBase->*m_func)(args...);
	}
private:
	T* m_pSlotBase = NULL;
	Func m_func;
};

template <class...Args>
class Signal
{
public:
	template<class T>
	void Bind(T* obj, void (T::*func)(Args...))
	{
		m_pSlotSet.push_back(new Slot<T, Args...>(obj, func));
	}

	void operator()(Args...args)
	{
		for (int i = 0; i < (int)m_pSlotSet.size(); i++)
		{
			m_pSlotSet[i]->Exec(args...);
		}
	}
private:
	vector< SlotBase<Args...>* > m_pSlotSet;
};


class TestFunc1
{
public:
	void FunOfA(int param)
	{
		cout << __FUNCTION__ << " " << param << endl;
	}
};

class TestFunc2
{
public:
	void FuncOfB(std::string param)
	{
		cout << __FUNCTION__ << " " << param.c_str() << endl;
	}
};

class TestFunc3
{
public:
	void FuncOfC(int parm1,std::string param2,float params3)
	{
		cout << __FUNCTION__ << " " << parm1 << " " << param2.c_str() << " " << params3 << endl;
	}
};

template<class...Args>
class TestSignal
{
public:
	TestSignal()
	{

	}
	void emit(Args...args)
	{
		ValueChanged(args...);
	}
public:
	Signal<Args...> ValueChanged;
};

#define Connect(sender,signal,receiver,method)((sender)->signal.Bind(receiver,method));
int main()
{
	TestFunc1* pFunc1 = new TestFunc1;
	TestFunc2* pFunc2 = new TestFunc2;
	TestFunc3* pFunc3 = new TestFunc3;
	TestSignal<int>* pSinal1 = new TestSignal<int>();
	TestSignal<std::string>* pSinal2 = new TestSignal<std::string>();
	TestSignal<int,std::string,float>* pSinal3= new TestSignal<int, std::string, float>();

	Connect(pSinal1, ValueChanged, pFunc1, &TestFunc1::FunOfA);
	Connect(pSinal2, ValueChanged, pFunc2, &TestFunc2::FuncOfB);
	Connect(pSinal3, ValueChanged, pFunc3, &TestFunc3::FuncOfC);

	pSinal1->emit(1);
	pSinal2->emit("hahhaha");
	pSinal3->emit(1,"heheh",2.3f);

	delete pFunc1;
	delete pFunc2;
	delete pSinal2;
	delete pSinal1;

	delete pFunc3;
	delete pSinal3;
	getchar();
	return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值