C++ 简单模拟QT信号槽

先看使用:

#include "stdafx.h"
#include "ConnecterSlot.h"

class A
{
public:
	A()
	{

	}

	~A()
	{

	}

private:
    // 定义一个信号
	SIGNAL(TestSignal)

public:
	void EmitSignal()
	{
		printf("A Signal Emit!!\r\n");

        // 触发这个信号
		EMIT(TestSignal)
	}
};

class B
{
public:
	B()
	{

	}
	~B()
	{

	}

public:
    // 测试时绑定的槽函数
	void DoSlot()
	{
		printf("B Slot Run!!\r\n");
	}

};

int main()
{
	A a;
	B b;

    // 将信号和槽绑定
	CONNECT(&a, TestSignal, &b, &B::DoSlot);
    
    // 触发信号
	a.EmitSignal();

	system("pause");
	return 0;
}

结果:

B的槽函数触发了。

实现原理:用宏定义将类的函数指针封装,模拟最简单的信号槽,为了防止误人子弟说明一下,这里只是简单的模拟,QT中的原理和这个完全不同。(QT的信号槽还是吊,居然还能跨线程~~)

//ConnecterSlot.h
#pragma once

#include <vector>

class ISloter
{
public:
	virtual ~ISloter() { };
	virtual void doFun() = 0;
};

template<typename T>
class Sloter : public ISloter
{
	typedef void(T::*CallBackFun)(void);

public:
	Sloter(T* obj, CallBackFun fun)
		: d_object(obj), m_callBackFun(fun)
	{

	}

	~Sloter()
	{

	}

private:
	T* d_object;
	CallBackFun m_callBackFun;

public:
	void doFun()
	{
		(d_object->*m_callBackFun)();
	}
};

class Signal
{
public:
	Signal()
	{

	}

	~Signal()
	{
		if (1 == m_slots.size())
		{
			delete m_slots[0];
		}
	}

private:
	std::vector<ISloter*> m_slots;

public:

	template<typename T>
	void regest(T* obj, void(T::*fun)(void))
	{

		if (0 == m_slots.size())
		{
			m_slots.push_back(new Sloter<T>(obj, fun));
		}
	}

	void doFun()
	{
		if (1 == m_slots.size())
		{
			m_slots[0]->doFun();
		}
	}
};

// 将信号与触发函数连起来
#define CONNECT(signalObj, signal, slotObj, slot) (signalObj)->get_##signal().regest(slotObj, slot);

// 注意这个宏会改变后面的成员的public/private/protect属性,用的时候请注意
// 定义信号
#define SIGNAL(signal) \
private: \
	Signal signal_##signal; \
public: \
	Signal& get_##signal() \
	{\
		return signal_##signal;\
	}\
private:
	
// 触发信号
#define EMIT(signal) signal_##signal.doFun();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值