1. 程式人生 > 其它 >C++ 簡單實現訊號槽

C++ 簡單實現訊號槽

技術標籤:C++c++

原理:儲存函式繫結類的函式指標,進行回撥。

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;

}