C++模拟QT信号槽实现

        Qt信号槽机制可以很好地实现全局广播,具有类型安全,耦合松散,使用灵活等优点。Qt信号槽的本质就是函数指针,现在用函数指针来模拟一下信号槽的实现。

        首先定义信号槽函数类。

class slotBase {
public:
	virtual void doit() = 0;
};
//槽函数
template<class Receive>
class slot:public slotBase {
	Receive *pRec;
	void (Receive::*pFunc)();
public:
	slot(Receive* pRec, void (Receive::*pFunc)()):pRec(pRec), pFunc(pFunc) {

	}
	void doit()
	{
		(pRec->*pFunc)();
	}
};

槽函数中包含了接受指针和槽函数指针。这里的为了方便理解,将信号和槽都假定为void类型的无参函数指针。随后定义信号类:

//信号
class signal {
public:
	template<class Receive>
	void Bind(Receive*pRec, void(Receive::*pFunc)()) {
		slotVecs.push_back(new slot<Receive>(pRec, pFunc));
	}
	void operator ()()
	{
		for (auto pFun : slotVecs) {
			pFun->doit();
		}
	}
	signal() {

	}
	//释放槽函数指针
	~signal()
	{
		for (auto pFun : slotVecs) {
			delete pFun;
			pFun = nullptr;
		}
	}

private:
	std::vector<slotBase*> slotVecs;
};

信号和槽的连接,相当于是一张表,一个信号可以对应多个槽函数。因此使用vector容器存放槽函数类。一个槽函数也可以被多个信号所连接,直接将信号和槽connect即可

#define connect(sender, signal, receiver, slot) ((sender)->signal.Bind(receiver, slot))

在发送信号时,将信号类中的vector函数指针容器遍历执行一遍即可。

//发送类
class Client {
public signals:
	signal sig;
	void sendMessage() {
		emit sig();
	}
};

//接收类
class Server {
public slots:
	void print() {
		std::cout << "received!!" << std::endl;
	}
};

int main()
{
	Client *client = new Client();
	Server *server = new Server();
	connect(client, sig, server, &Server::print);
	client->sendMessage();

	delete client;
	client = nullptr;
	delete server;
	server = nullptr;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值