• c++通过类名动态创建对象


    转载:http://www.seacha.com/article.php/knowledge/cbase/2013/0615/2154.html

    主要思想:在每次创建类的过程中,通过各自类的辅助类(所以每个类必须包含IMPLEMENT_DYNCRT_BASE)向基类通过“注册函数'注册,然后通过重载“工厂函数”,在创建类时,自身创建类。这里函数指针的使用非常重要。

    #include <map>
    #include <string>
    
    #define DECLEAR_DYNCRT_BASE(CBase) 
        public: 
            typedef CBase *(*ClassGen)(); /* 声明函数指针*/ 
            static CBase *Create(const string &class_name) /* 工厂函数 */ 
            { 
                std::map<string, ClassGen>::iterator iter = m_class_set.find(class_name); 
                if (m_class_set.end() != iter) 
                { 
                    return ((*iter).second)(); 
                } 
                return NULL; 
            } 
        protected: 
            static void Register(const string &class_name, ClassGen class_gen) /* 注册函数 */ 
            { 
                m_class_set.insert(map<string, ClassGen>::value_type(class_name, class_gen)); 
            } 
            static std::map<string, ClassGen> m_class_set /* 存储子类信息 */
    
    // 用于实现基类
    #define IMPLEMENT_DYNCRT_BASE(CBase) 
        std::map<string, CBase::ClassGen> CBase::m_class_set
    
    #define DECLEAR_DYNCRT_CLASS(CDerived, CBase) 
        public: 
            struct CDerived##Register /* 辅助类,用于注册 */ 
            { 
                CDerived##Register() 
                { 
                    static bool bRegistered = false; /* 注册子类,只注册一次 */ 
                    if(!bRegistered) 
                    { 
                        CBase::Register(#CDerived, CDerived::Create); /* 注册子类信息 */ 
                        bRegistered = true; 
                    } 
                } 
            }; 
            static CBase *Create() /* 工厂函数 */ 
            { 
                return new CDerived; 
            } 
            static struct CDerived##Register m_t##CDerived##Register
    
    
    // 用于实现一个能被动态创建的类
    #define IMPLEMENT_DYNCRT_CLASS(CDerived) 
        static CDerived::CDerived##Register m_t##CDerived##Register
    
    
    
    class CBase
    {
        DECLEAR_DYNCRT_BASE(CBase);
        DECLEAR_DYNCRT_CLASS(CBase, CBase);
        public:
            virtual void Print()
            {
                std::cout << "This is base!" << std::endl;
            }
    };
    
    IMPLEMENT_DYNCRT_BASE(CBase);
    IMPLEMENT_DYNCRT_CLASS(CBase);
    
    
    class TEST: public CBase
    {
        DECLEAR_DYNCRT_CLASS(TEST, CBase);
        public:
            virtual void Print()
            {
                cout << "This is test!" << endl;
            }
    };
    IMPLEMENT_DYNCRT_CLASS(TEST);
    
    int main()
    {
        CBase* base = CBase::Create("TEST");
        if (base)
        {
            base->Print();
        }
    
        return 0;
    }
  • 相关阅读:
    新经资讯项目业务逻辑梳理
    HTTP状态保持的原理
    CSRF的原理和防范措施
    装饰器路由具体实现梳理
    Flask中异常捕获
    正则匹配路由
    (搬运以学习)flask 上下文的实现
    flask之请求钩子
    如何在linux中创建虚拟环境
    面包屑导航
  • 原文地址:https://www.cnblogs.com/hansjorn/p/5239932.html
Copyright © 2020-2023  润新知