• 管理器注册类方法和调用类函数方法


    重点:

    1.将要创建的类管理起来,当面临一类构件的注册管理的实现。

    2.包括调用函数内部类方法。

    一:定义结构体和基类

    Define.h

    1. enum class MyType
    2. {
    3. red,
    4. blue,
    5. green,
    6. black
    7. };
    8. class BaseTool
    9. {
    10. public:
    11. BaseTool() = default;
    12. virtual ~BaseTool()=default;
    13. private:
    14. };

    二:设计单例管理类

    RegMananger.h

    1. #pragma once
    2. #include "Define.h"
    3. #include
    4. #include
    5. #include
    6. class ICreator
    7. {
    8. public:
    9. virtual ~ICreator() {}
    10. virtual std::shared_ptr Create() = 0;
    11. };
    12. //单例管理注册信息
    13. class RegMananger
    14. {
    15. public:
    16. static RegMananger& Getinstance();
    17. RegMananger(const RegMananger&) = delete;
    18. RegMananger& operator=(const RegMananger&) = delete;
    19. public:
    20. void AddMananger(MyType type, ICreator* create);
    21. std::shared_ptr GetEditor(MyType type);
    22. private:
    23. RegMananger();
    24. ~RegMananger();
    25. //保证类的私密性
    26. struct Impl;
    27. Impl* m_pData;
    28. };
    29. //计算可变参数个数,限制在20个
    30. #define ARG_T(t) t //解决VC编译错误
    31. #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]
    32. #define ARG_N_HELPER(...) ARG_T(ARG_N(__VA_ARGS__)) //辅助宏
    33. #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) //返回可变参数个数
    34. //注册宏函数
    35. #define REG_TOOL(CLASSNAME, ...) \
    36. class AutoReg##CLASSNAME :public ICreator \
    37. { \
    38. public:\
    39. AutoReg##CLASSNAME()\
    40. {\
    41. std::set&& typeSet{GetType(COUNT_ARG(__VA_ARGS__),__VA_ARGS__)};\
    42. for (auto& var:typeSet)\
    43. {\
    44. RegMananger::Getinstance().AddMananger(var,this);\
    45. }\
    46. }\
    47. public: \
    48. virtual std::shared_ptr Create() override \
    49. { \
    50. return std::make_shared(); \
    51. } \
    52. private: \
    53. std::set GetType(int n, ...)\
    54. {\
    55. std::set myType; \
    56. va_list args; \
    57. va_start(args, n); \
    58. while (n--)\
    59. {\
    60. MyType ty = va_arg(args, MyType); \
    61. myType.insert(ty); \
    62. }\
    63. va_end(args); \
    64. return myType; \
    65. }\
    66. }; \
    67. static AutoReg##CLASSNAME _regEditorCreator##CLASSNAME; \
    68. //通过static去实现实例化

    RegMananger.cpp 

    1. #include
    2. #include "RegMananger.h"
    3. struct RegMananger::Impl
    4. {
    5. std::map m_mapEditor;
    6. };
    7. RegMananger& RegMananger::Getinstance()
    8. {
    9. static RegMananger m_instance;
    10. return m_instance;
    11. }
    12. RegMananger::RegMananger()
    13. {
    14. m_pData = new Impl();
    15. }
    16. RegMananger::~RegMananger()
    17. {
    18. delete m_pData;
    19. }
    20. void RegMananger::AddMananger(MyType type, ICreator* create)
    21. {
    22. m_pData->m_mapEditor[type] = create;
    23. }
    24. std::shared_ptr RegMananger::GetEditor(MyType type)
    25. {
    26. auto iter = m_pData->m_mapEditor.find(type);
    27. if (iter == m_pData->m_mapEditor.end())
    28. {
    29. return nullptr;
    30. }
    31. return iter->second->Create();
    32. }

    三:注册类

    RegMananger.h

    1. #pragma once
    2. #include "Define.h"
    3. class RedColorTool:public BaseTool
    4. {
    5. public:
    6. RedColorTool() = default;
    7. ~RedColorTool() = default;
    8. private:
    9. int data;
    10. };

    RegMananger.cpp 

    1. #include "RedColor.h"
    2. #include "RegMananger.h"
    3. REG_TOOL(RedColorTool, MyType::red, MyType::blue);

    四:调用基类

    BaseCmd.h

    1. #pragma once
    2. #include "RegMananger.h"
    3. class BaseCmd
    4. {
    5. public:
    6. BaseCmd() = default;
    7. virtual ~BaseCmd() = default;
    8. void SetType(MyType type) { m_type = type; };
    9. std::shared_ptr GetBaseTool()
    10. {
    11. return RegMananger::Getinstance().GetEditor(m_type);
    12. };
    13. protected:
    14. template<class _Tool, class _Ret, class ..._Arg>
    15. //_Ret:返回值,_Tool类名称,func:static函数,_Arg:函数传入参数
    16. _Ret InvokeTool(_Ret(_Tool::* func)(_Arg...), std::remove_cv_t<_Arg>... args)
    17. {
    18. std::shared_ptr<_Tool> spEditor = std::dynamic_cast<_Tool*>(GetBaseTool());
    19. if (spEditor)
    20. {
    21. if constexpr (std::is_same_v<_Ret,void>)
    22. {
    23. (spEditor.get()->*func)(std::forward<_Arg>(args)...);
    24. }
    25. else
    26. {
    27. return (spEditor.get()->*func)(std::forward<_Arg>(args)...);
    28. }
    29. }
    30. else
    31. {
    32. std::cout << "class Error" << std::endl;
    33. }
    34. if constexpr (!std::is_same_v<_Ret, void>)
    35. {
    36. return _Ret{};
    37. }
    38. }
    39. private:
    40. MyType m_type;
    41. };

     五:普通类

    1. #pragma once
    2. #include "Define.h"
    3. #include "RegMananger.h"
    4. class ColorTool :public BaseTool
    5. {
    6. public:
    7. ColorTool() =default;
    8. ~ColorTool() = default;
    9. bool Create(int num,bool check);
    10. private:
    11. };
    12. bool ColorTool::Create(int num, bool check)
    13. {
    14. return true;
    15. }
    16. REG_TOOL(ColorTool, MyType::red, MyType::blue);

    六:继承调用类

    1. #pragma once
    2. #include "BaseCmd.h"
    3. #include "ColorTool.h"
    4. class NewColorCmd:public BaseCmd
    5. {
    6. public:
    7. NewColorCmd() { SetType(MyType::red); };
    8. ~NewColorCmd()=default;
    9. void Create();
    10. private:
    11. };
    12. void NewColorCmd::Create()
    13. {
    14. int num = 10;
    15. bool check = true;
    16. InvokeTool(&ColorTool::Create, num, check);
    17. }

  • 相关阅读:
    Java中的抽象类和接口
    OpenWRT配置SFTP远程文件传输,实现数据安全保护
    【设计模式之策略模式 -- C++】
    使用uni-app组件播放视频
    JAVA-----抽象类和接口
    N-129基于springboot,vue学生宿舍管理系统
    MODB:软体动物线粒体基因组数据库
    2-2Linux下文件操作常用命令
    Leetcode T34: 在排序数组中查找元素的第一个和最后一个位置
    长连接和短连接
  • 原文地址:https://blog.csdn.net/qq_38409301/article/details/133721200