委托——探索之旅

委托是一个类,其内部维护一个装有函数包装器的容器。函数包装器把函数指针封装成类,这样使得需要委托的函数能够像普通对象一样作为参数传递。究其根本委托的核心为函数指针,而函数指针为C语言的多态思想,所以在面向对象语言中委托也可以作为一种多态手段。

#pragma once
#include <cstdint>
#include <unordered_map>
#include <functional>

template<typename T>
class Delegate
{
public:
 	void connect(std::function<T> func)
 	{
		uint32_t index = convertPtrToUInt(&func);
		if (_delegateMap.find(index) == _delegateMap.end())
 		{
 			_delegateMap.insert(std::make_pair(index, func));
 		}
	}
 	void disconnect(std::function<T> func)
 	{
		uint32_t index = convertPtrToUInt(&func);
		if (_delegateMap.find(index) != _delegateMap.end())
 		{
 			_delegateMap.erase(index); 
 		}
 	}
	void operator += (std::function<T> func)
	{
		connect(func);
	}
	void operator -= (std::function<T> func)
	{
		disconnect(func);
	}
	template<typename ... Args>
	void operator ()(Args&& ... args)
	{
		for (auto var : _delegateMap)
		{
			var.second(std::forward<Args>(args) ...);
		}
	}
private:
	inline uint32_t convertPtrToUInt(void* fptr)
	{
		uint32_t value = 0;
		memcpy_s(&value, sizeof(uint32_t), fptr, sizeof(void*));
		return value;
	}
	std::unordered_map<uint32_t, std::function<T> > _delegateMap;
};


//测试代码
class Test1
{
public:
	void function1()
	{
		std::cout << "call Test1::function1" << std::endl;
	}
	void function2(int param1)
	{
		std::cout << "call Test1::function2 and param1 is " << param1 << std::endl;
	}
};

void function1(int param1)
{
	std::cout << "call function and param1 is " << param1 << std::endl;
}

typedef void(__stdcall *Fun)(int a);

void __stdcall dllFunc(int param1)
{
	std::cout << "call testDllFunc and param1 is " << param1 << std::endl;
}

void delegateTest()
{
	Test1 testObj1;
	
	Delegate<void()> delegateHandler0;
	delegateHandler0.connect(std::bind(&Test1::function1, testObj1));
	delegateHandler0();
	
	Delegate<void(int)> delegateHandler1;
	delegateHandler1.connect(function1);
	delegateHandler1.connect(std::bind(&Test1::function2, testObj1, std::placeholders::_1));
	delegateHandler1(1);

      Fun func=dllFunc;
      Delegate<void(int)>
  
  
   
    delegateHandler;
	delegateHandler += std::bind(func, std::placeholders::_1);
	delegateHandler(33);
}
  
  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值