#include<iostream>
#include<vector>
#include "Functional"
/**
* 所涉及的知识点:
* (1)typedef的函数指针定义方式
* (2)Using的函数指针定义方式
* (3)单播绑定和执行的过程(C++仿照UE)
* (4)Function的使用——bind以及对这种包装器(std::function<void(int, int)> )的使用
* (5)多播的实现(Fdelegate的类中的private变量用Vector保存函数包装器)
* (6)使用宏编程的方式
* (7)使用模板方式定义委托(避免重复写委托类)、
* (8)可变参数的使用
*/
/* 普通版本
//使用typedef方式对函数指针的定义
typedef void(*FunMethod)(int, int);
using FuncMethod1 = int(*)(int, int);
class TestA
{
public:
void LessNum(int a, int b)
{
const int c = a - b;
std::cout << "a - b = " << c << std::endl;
}
void LessNum1(int a, int b)
{
const int c = b - a;
std::cout << "b - a = " << c << std::endl;
}
};
typedef void(TestA::* LessFunMethod)(int, int);
using LessFunMethod1 = int(TestA::*)(int, int);
class FDelegateTwoParams
{
public:
//绑定的是一个全局方法
void BindRaw(FunMethod FunPtr, int a, int b)
{
FunArray.push_back(std::bind(FunPtr, a, b));
}
//绑定一个类的成员方法
void BindRaw2(TestA* UserClass, LessFunMethod FunPtr, int a, int b)
{
FunArray.push_back(std::bind(FunPtr, UserClass, a, b));
}
void BindStatic()
{
}
bool IsBound()const
{
return !FunArray.empty() ? true : false;
}
void Excute()
{
for (auto Fun : FunArray)
{
Fun(0, 0);
}
}
void Broadcast()
{
for (auto Fun : FunArray)
{
Fun(0, 0);
}
}
bool ExcuteIfBound()
{
if (IsBound())
{
Excute();
return true;
}
return false;
}
private:
std::vector<std::function<void(int, int)>> FunArray;
};
void AddNum(int a, int b)
{
const int c = a + b;
std::cout << "a + b = " << c << std::endl;
}
int main()
{
//(1)typedef的函数指针定义方式
FunMethod fun1 = &AddNum;
fun1(5, 7);
// 单播测试绑定全局函数
//FDelegateTwoParams Delegate;
//Delegate.BindRaw(&AddNum, 5, 8);
//Delegate.Excute();
// 单播测试绑定其他类的成员函数(加入多播多播的Vector设置)
FDelegateTwoParams Delegate;
TestA* UserClass = new TestA();
Delegate.BindRaw2(UserClass, &TestA::LessNum, 100, 10);
Delegate.BindRaw(&AddNum, 100, 10);
Delegate.Broadcast();
system("pause");
}
*/
/**
* 宏编程版本
*/
class TestA
{
public:
void FunNoparam()
{
std::cout << "Hello Delegate"<<std::endl;
};
void FunTwoParam(int a, int b)
{
std::cout << "a + b = " << a + b << std::endl;
}
};
// 函数指针的两种定义方式
typedef void (*FunMethodNoParam1)(void);
using FunMethodNoParam = void(TestA::*)(void);
// 无参数单播委托
#define DECLARE_DELEGATE(DelegateName)\
class F##DelegateName\
{\
public:\
void BindRaw2(TestA * UserClass, FunMethodNoParam FunPtr)\
{\
Fun = std::bind(FunPtr, UserClass); \
}\
bool IsBound()\
{\
return Fun ? true : false; \
}\
void Excute()\
{\
Fun(); \
}\
bool ExcuteIfBound()\
{\
if (IsBound())\
{\
Excute(); \
return true; \
}\
return false; \
}\
private:\
std::function<void()> Fun; \
};
// 函数指针的两种定义方式
typedef void (TestA::* FunMethodTwoParam1)(int, int);
using FunMethodTwoParam = void(TestA::*)(int, int);
// 两个参数的单播委托
#define DECLARE_DELEGATE_TwoParams(DelegateName, ParamType1, ParamType2)\
class F##DelegateName\
{\
public:\
void BindRaw2(TestA * UserClass, FunMethodTwoParam FunPtr, ParamType1 t1, ParamType2 t2)\
{\
Fun = std::bind(FunPtr, UserClass, t1, t2); \
}\
bool IsBound()\
{\
return Fun ? true : false; \
}\
void Excute()\
{\
Fun(); \
}\
bool ExcuteIfBound()\
{\
if (IsBound())\
{\
Excute(); \
return true; \
}\
return false; \
}\
private:\
std::function<void()> Fun; \
};
// 对于单播来说,后面的;可以加,也可以不加,因为在宏定义中已经有了
// 委托的声明
DECLARE_DELEGATE(TestDelegateNoParam);
DECLARE_DELEGATE_TwoParams(TestDelegateTwoParam, int, int);
//int main()
//{
// // 注意前面要加上F,因为宏的定义
// FTestDelegateNoParam Delegate;
// TestA* ObjPtr = new TestA;
// Delegate.BindRaw2(ObjPtr, &TestA::FunNoparam);
// Delegate.Excute();
// system("pause");
//}
/**
* 模板编程版本
*/
template<typename Class,typename RetType,typename...ArgTypes>
struct TMemFunPtrType
{
typedef RetType(Class::* Type)(ArgTypes...);
};
template<typename RetValType,typename... ParamTypes>
class TBaseDelegate
{
public:
template<typename UserClass, typename... Types>
void BindRaw(UserClass* MyUserClass,
typename TMemFunPtrType<UserClass, RetValType, Types...>::Type FunPtr, Types... Vars)
{
Fun = std::bind(FunPtr, MyUserClass, Vars...);
}
bool IsBound()
{
return Fun ? true : false;
}
void Excute()
{
Fun();
}
bool ExcuteIfBound()
{
if (IsBound())
{
Excute();
return true;
}
return false;
}
private:
std::function<RetValType()>Fun;
};
// 单播无参数
#define DECLARE_DELEGATE(DelegateName) \
class DelegateName : public TBaseDelegate<void>{};
#define DECLARE_DELEGATE_TwoParam(DelegateName,ParamType1,ParamType2)\
class DelegateName : public TBaseDelegate<void, ParamType1, ParamType2>{};
#define DECLARE_DELEGATE_RetVal_TwoParam(RetType,DelegateName,ParamType1,ParamType2)\
class DelegateName : public TBaseDelegate<RetType, ParamType1, ParamType2>{};
DECLARE_DELEGATE(TestDelegateNameNoParam);
DECLARE_DELEGATE_TwoParam(TestDelegateTwoParam, int, int);
DECLARE_DELEGATE_RetVal_TwoParam(int, TestDelegateTwoParamRet, int, int);
class TestB
{
public:
void T()
{
std::cout << "Hello World !!!" << std::endl;
}
void TA(int a, int b)
{
std::cout << "a + b = " << a + b << std::endl;
}
int Minus(int c, int d)
{
std::cout << "c - d : " << std::endl;
return c - d;
}
};
int main()
{
TestDelegateNameNoParam TDelegate;
TestB ObjPtr;
TDelegate.BindRaw(&ObjPtr, &TestB::T);
TDelegate.Excute();
TestDelegateTwoParam Delegate;
Delegate.BindRaw(&ObjPtr, &TestB::TA, 90, 10);
Delegate.Excute();
TestDelegateTwoParamRet DelegateRet;
DelegateRet.BindRaw(&ObjPtr, &TestB::Minus, 100, 10);
DelegateRet.Excute();
system("pause");
}
C++实现UE委托
最新推荐文章于 2024-02-07 09:52:14 发布