重点:
1.将要创建的类管理起来,当面临一类构件的注册管理的实现。
2.包括调用函数内部类方法。
一:定义结构体和基类
Define.h
- enum class MyType
- {
- red,
- blue,
- green,
- black
- };
-
- class BaseTool
- {
- public:
- BaseTool() = default;
- virtual ~BaseTool()=default;
-
- private:
-
- };
二:设计单例管理类
RegMananger.h
- #pragma once
- #include "Define.h"
- #include
- #include
- #include
-
- class ICreator
- {
- public:
- virtual ~ICreator() {}
- virtual std::shared_ptr
Create() = 0; - };
-
- //单例管理注册信息
- class RegMananger
- {
- public:
- static RegMananger& Getinstance();
-
- RegMananger(const RegMananger&) = delete;
- RegMananger& operator=(const RegMananger&) = delete;
-
- public:
- void AddMananger(MyType type, ICreator* create);
- std::shared_ptr
GetEditor(MyType type) ; - private:
- RegMananger();
- ~RegMananger();
-
- //保证类的私密性
- struct Impl;
- Impl* m_pData;
- };
-
- //计算可变参数个数,限制在20个
- #define ARG_T(t) t //解决VC编译错误
- #define ARG_N(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,N,...) N //截取并返回第四个参数,这里限制了可变参数计算的范围[1,4]
- #define ARG_N_HELPER(...) ARG_T(ARG_N(__VA_ARGS__)) //辅助宏
- #define COUNT_ARG(...) ARG_N_HELPER(__VA_ARGS__,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) //返回可变参数个数
-
-
-
- //注册宏函数
- #define REG_TOOL(CLASSNAME, ...) \
- class AutoReg##CLASSNAME :public ICreator \
- { \
- public:\
- AutoReg##CLASSNAME()\
- {\
- std::set
&& typeSet{GetType(COUNT_ARG(__VA_ARGS__),__VA_ARGS__)};\ - for (auto& var:typeSet)\
- {\
- RegMananger::Getinstance().AddMananger(var,this);\
- }\
- }\
- public: \
- virtual std::shared_ptr
Create() override \ - { \
- return std::make_shared
(); \ - } \
- private: \
- std::set
GetType(int n, ...)\ - {\
- std::set
myType; \ - va_list args; \
- va_start(args, n); \
- while (n--)\
- {\
- MyType ty = va_arg(args, MyType); \
- myType.insert(ty); \
- }\
- va_end(args); \
- return myType; \
- }\
- }; \
- static AutoReg##CLASSNAME _regEditorCreator##CLASSNAME; \
- //通过static去实现实例化
RegMananger.cpp
- #include
- #include "RegMananger.h"
-
- struct RegMananger::Impl
- {
- std::map
m_mapEditor; - };
-
- RegMananger& RegMananger::Getinstance()
- {
- static RegMananger m_instance;
- return m_instance;
- }
-
- RegMananger::RegMananger()
- {
- m_pData = new Impl();
- }
-
- RegMananger::~RegMananger()
- {
- delete m_pData;
- }
-
- void RegMananger::AddMananger(MyType type, ICreator* create)
- {
- m_pData->m_mapEditor[type] = create;
- }
-
- std::shared_ptr
RegMananger::GetEditor(MyType type) - {
- auto iter = m_pData->m_mapEditor.find(type);
- if (iter == m_pData->m_mapEditor.end())
- {
- return nullptr;
- }
-
- return iter->second->Create();
- }
三:注册类
RegMananger.h
- #pragma once
- #include "Define.h"
-
-
-
- class RedColorTool:public BaseTool
- {
- public:
- RedColorTool() = default;
- ~RedColorTool() = default;
-
- private:
- int data;
- };
-
RegMananger.cpp
- #include "RedColor.h"
- #include "RegMananger.h"
-
- REG_TOOL(RedColorTool, MyType::red, MyType::blue);
四:调用基类
BaseCmd.h
- #pragma once
- #include "RegMananger.h"
-
- class BaseCmd
- {
- public:
- BaseCmd() = default;
- virtual ~BaseCmd() = default;
-
- void SetType(MyType type) { m_type = type; };
- std::shared_ptr
GetBaseTool() - {
- return RegMananger::Getinstance().GetEditor(m_type);
- };
-
- protected:
- template<class _Tool, class _Ret, class ..._Arg>
- //_Ret:返回值,_Tool类名称,func:static函数,_Arg:函数传入参数
- _Ret InvokeTool(_Ret(_Tool::* func)(_Arg...), std::remove_cv_t<_Arg>... args)
- {
- std::shared_ptr<_Tool> spEditor = std::dynamic_cast<_Tool*>(GetBaseTool());
- if (spEditor)
- {
- if constexpr (std::is_same_v<_Ret,void>)
- {
- (spEditor.get()->*func)(std::forward<_Arg>(args)...);
- }
- else
- {
- return (spEditor.get()->*func)(std::forward<_Arg>(args)...);
- }
- }
- else
- {
- std::cout << "class Error" << std::endl;
- }
-
- if constexpr (!std::is_same_v<_Ret, void>)
- {
- return _Ret{};
- }
- }
-
- private:
- MyType m_type;
- };
五:普通类
- #pragma once
- #include "Define.h"
- #include "RegMananger.h"
-
- class ColorTool :public BaseTool
- {
- public:
- ColorTool() =default;
- ~ColorTool() = default;
-
- bool Create(int num,bool check);
- private:
-
- };
-
- bool ColorTool::Create(int num, bool check)
- {
- return true;
- }
-
- REG_TOOL(ColorTool, MyType::red, MyType::blue);
六:继承调用类
- #pragma once
- #include "BaseCmd.h"
- #include "ColorTool.h"
-
- class NewColorCmd:public BaseCmd
- {
- public:
- NewColorCmd() { SetType(MyType::red); };
- ~NewColorCmd()=default;
-
- void Create();
- private:
-
- };
-
- void NewColorCmd::Create()
- {
- int num = 10;
- bool check = true;
- InvokeTool(&ColorTool::Create, num, check);
- }