美文网首页
C++ 简单工厂模式与反射机制

C++ 简单工厂模式与反射机制

作者: 从不中二的忧伤 | 来源:发表于2020-06-06 12:08 被阅读0次

    Java的反射机制是指在程序运行状态中,构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。

    问题引入:

    那么C++中能否实现类似的反射机制,根据给定的字符串(类的名字),生成类的对象呢?

    简单工厂模式:
    #include <iostream>
    using namespace std;
    
    class Base
    {
    public:
        virtual void print()
        {
            cout << "Base" << endl;
        }
    };
    
    class Derive1 : public Base
    {
    public:
        virtual void print()
        {
            cout << "Derive1" << endl;
        }
    };
    
    class Derive2 : public Base
    {
    public:
        virtual void print()
        {
            cout << "Derive2" << endl;
        }   
    };
    
    
    
    class Factory
    {
    public:
        static Base* build(const string& className)
        {
            if("Derive1" == className)
            {
                return new Derive1; 
            }
            if("Derive2" == className)
            {
                return new Derive2; 
            }
            return 0;
        }
    };
    
    int main()
    {   
        Base* p1 = Factory::build("Derive1");
        p1->print();
        
        Base* p2 = Factory::build("Derive2");
        p2->print();
    
        return 0;
    }
    

    通过简单工厂模式,的确可以实现根据"类名字符串",生成对应的对象。但是,这种操作下,一旦需要新增类时,就必须修改 生成对象的 Factory 类。 有没有什么办法能够不需要修改 Factory呢?
    其实通过回调函数引入“注册”机制,就能比较好的实现这一想法:

    工厂模式结合注册机制
    方法一:

    为了实现反射,可以设计以下四种角色:


    一、工厂类

    1. 单例模式,保证只有一份实例
    2. 维护私有 map 用于记录 应用类名 - 应用类的反射成员
    3. 提供注册接口,用于注入 应用类名 - 应用类的反射成员
    4. 提供获取应用类的实例接口,通过维护的 应用类的反射成员应用类的回调函数 初始化应用类的实例

    二、 反射类

    1. 维护应用类的 类名类的回调函数
    2. 在构造函数中,调用工厂的注册接口
    3. 提供调用回调函数的接口,用以初始化应用类的实例

    三、基类

    1. 用于承载回调函数类型

    四、应用类(子类)

    1. 维护应用类的反射类
    2. 定义回调函数,返回应用类的实例
    3. 应用成员......
    4. 实例化应用类的反射类,以实现在反射类的构造函数中向工厂类注册入map

    一、工厂类:

    class Factory
    {
    private:
        Factory(){ cout << "Factory()" << endl; }
        
    public:
        ~Factory(){ cout << "~Factory()" << endl; }
        
    public:
        static Factory& getInstance();
        
        // 将子类的 Reflector 指针注册到 map 中 
        void Register(Reflector* reflector);
        
        // 根据类名返回实例 
        Base* getObject(string className);
    
    private:
        map<string, Reflector*> objectMap;
    };
    
    
    
    Factory& Factory::getInstance()
    {
        static Factory factory;
        return factory;
    }
    
    void Factory::Register(Reflector* reflector)
    {
        if (reflector)
        {
            objectMap.insert(map<string, Reflector*>::value_type(reflector->m_cname, reflector));
        }
    }
    
    Base* Factory::getObject(string className)
    {
        map<string, Reflector*>::const_iterator iter = objectMap.find(className);
        if (iter != objectMap.end())
        {
            return iter->second->getObjectInstance();
        }
    }
    



    二、反射类

    typedef Base* (*ObjectConstructor)();
    class Reflector
    {
    public:
        Reflector(string name, ObjectConstructor objc) : m_cname(name), m_objc(objc)
        {
            cout << "Reflector()" << endl;
            Factory::getInstance().Register(this);
        }
        virtual ~Reflector(){ cout << "~Reflector()" << endl; }
        
        Base* getObjectInstance();
    
    public:
        string m_cname;
        ObjectConstructor m_objc;
    };
    
    Base* Reflector::getObjectInstance()
    {
        return m_objc();    
    } 
    



    三、基类

    // 支持反射的基类
    class Base
    {
    public:
        Base(){ cout << "Base()" << endl; }
        virtual ~Base(){ cout << "~Base()" << endl; }
        virtual void print(){
            cout << "Base print()" << endl;
        }
    };
    



    四、应用类

    class Derive : public Base
    {
    public:
        Derive(){ cout << "Derive()" << endl; }
        virtual ~Derive(){ cout << "~Derive()" << endl; }
        
        static Base* CreateObject()
        {
            return new Derive;
        }
        
        void print()
        {
            cout << "Derive print()" << endl;
        }
        
    protected:
        static Reflector m_reflector;   
    };
    Reflector Derive::m_reflector("Derive", Derive::CreateObject);
    

    主函数调用:

    int main()
    {   
        Base* p = Factory::getInstance().getObject("Derive");
        if (p)
        {
            p->print();
        }
        delete p;
        
        return 0;
    }
    

    根据应用类的实现,可以看到,每个支持反射的应用类,都需要写相同的 CreateObject() 和 m_reflector。以及都需要去初始化自身的 m_reflector 实现注册。实际上,如果写好宏定义,每个应用类需要的代码量就会大大减少:


    宏定义实现:

    #define DELCLARE_CLASS(className) \
        public: \
            static Base* CreateObject() \
            {   \
                return new className;   \
            }   \
        protected:  \
            static Reflector m_reflector;   \
    
    #define REGISTER_CLASS(className) \
        Reflector className::m_reflector(#className, className::CreateObject);
    

    应用类定义:

    class Derive : public Base
    {
    DELCLARE_CLASS(Derive);
    
    public:
        Derive(){ cout << "Derive()" << endl; }
        virtual ~Derive(){ cout << "~Derive()" << endl; }
        
        void print()
        {
            cout << "Derive print()" << endl;
        }
            
    };
    REGISTER_CLASS(Derive);
    

    完整代码实现:

    reflect_1.h

    #ifndef _REFLECT_1_H_
    #define _REFLECT_1_H_
    
    #include <iostream>
    #include <map>
    
    using namespace std;
    
    class Reflector;
    
    // 支持反射的基类
    class Base
    {
    public:
        Base(){ cout << "Base()" << endl; }
        virtual ~Base(){ cout << "~Base()" << endl; }
        virtual void print(){
            cout << "Base print()" << endl;
        }
    };
    
    // 工厂类 
    // - 提供注册接口,注册子类的 Reflector 对象
    // - 提供返回创建对象接口,根据子类类名返回实例
    class Factory
    {
    private:
        Factory(){ cout << "Factory()" << endl; }
        
    public:
        ~Factory(){ cout << "~Factory()" << endl; }
        
    public:
        static Factory& getInstance();
        
        // 将子类的 Reflector 指针注册到 map 中 
        void Register(Reflector* reflector);
        
        // 根据类名返回实例 
        Base* getObject(string className);
    
    private:
        map<string, Reflector*> objectMap;
    };
    
    
    typedef Base* (*ObjectConstructor)();
    
    // 实现反射的类 
    // - 构造时将自身的(实际上就是子类的) className 和 Reflector写入 map 中
    // - 回调函数实现返回子类的实例 
    class Reflector
    {
    public:
        Reflector(string name, ObjectConstructor objc) : m_cname(name), m_objc(objc)
        {
            cout << "Reflector()" << endl;
            Factory::getInstance().Register(this);
        }
        virtual ~Reflector(){ cout << "~Reflector()" << endl; }
        
        Base* getObjectInstance();
    
    public:
        string m_cname;
        ObjectConstructor m_objc;
    };
    
    // impl
    Factory& Factory::getInstance()
    {
        static Factory factory;
        return factory;
    }
    
    void Factory::Register(Reflector* reflector)
    {
        if (reflector)
        {
            objectMap.insert(map<string, Reflector*>::value_type(reflector->m_cname, reflector));
        }
    }
    
    Base* Factory::getObject(string className)
    {
        map<string, Reflector*>::const_iterator iter = objectMap.find(className);
        if (iter != objectMap.end())
        {
            return iter->second->getObjectInstance();
        }
    }
    
    
    Base* Reflector::getObjectInstance()
    {
        return m_objc();    
    } 
    
    
    #define DELCLARE_CLASS(className) \
        public: \
            static Base* CreateObject() \
            {   \
                return new className;   \
            }   \
        protected:  \
            static Reflector m_reflector;   \
    
    #define REGISTER_CLASS(className) \
        Reflector className::m_reflector(#className, className::CreateObject);
    
    
    #endif
    



    reflect_1.cpp

    #include "reflect_1.h"
    
    #include <iostream>
    
    using namespace std;
    
    // 支持反射的子类
    class Derive : public Base
    {
    DELCLARE_CLASS(Derive);
    
    public:
        Derive(){ cout << "Derive()" << endl; }
        virtual ~Derive(){ cout << "~Derive()" << endl; }
        
        void print()
        {
            cout << "Derive print()" << endl;
        }
            
    };
    REGISTER_CLASS(Derive);
    
    class Derive2 : public Base
    {
    DELCLARE_CLASS(Derive2);
    
    public:
        void print()
        {
            cout << "Derive2 print()" << endl;
        }
    };
    REGISTER_CLASS(Derive2);
    
    int main()
    {   
        Base* p = Factory::getInstance().getObject("Derive");
        if (p)
        {
            p->print();
        }
        delete p;
        
        Base* p2 = Factory::getInstance().getObject("Derive2");
        if (p2)
        {
            p2->print();
        }
        delete p2;
        
        return 0;
    }
    

    方法二:

    目前为止,已经实现了C++的反射机制,但是是否有继续优化的空间呢~?
    其实在工厂类维护 map 的时候,可以直接维护 类名 - 类的函数指针 ,不需要通过 Reflector 再转一层。

    基类:

    // 支持反射的基类
    class Base
    {
    public:
        Base(){ cout << "Base()" << endl; }
        virtual ~Base(){ cout << "~Base()" << endl; }
        
        virtual void print(){
            cout << "Base print()" << endl;
        }
    };
    
    typedef Base* (*ObjectConstructor)();
    



    工厂类:
    注意维护的 map 已变成 map<string, ObjectConstructor> objectMap; 在getObject中,直接iter->second() 即返回了对应的 Base*。

    class Factory
    {
    private:
        Factory(){ cout << "Factory()" << endl; }
        
    public:
        ~Factory(){ cout << "~Factory()" << endl; }
        
    public:
        static Factory& getInstance();
        
        void Register(string className, ObjectConstructor objc);
        
        Base* getObject(string className);
    
    private:
        map<string, ObjectConstructor> objectMap;
    };
    
    
    
    Factory& Factory::getInstance()
    {
        static Factory factory;
        return factory;
    }
    
    void Factory::Register(string className, ObjectConstructor m_objc)
    {
        if (m_objc)
        {
            objectMap.insert(map<string, ObjectConstructor>::value_type(className, m_objc));
        }
    }
    
    Base* Factory::getObject(string className)
    {
        map<string, ObjectConstructor>::const_iterator iter = objectMap.find(className);
        if (iter != objectMap.end())
        {
            return iter->second();
        }
    }
    



    反射类
    反射类中无需再维护应用类的 类名 和 ObjectConstructor

    class Reflector
    {
    public:
        Reflector(string name, ObjectConstructor objc)
        {
            cout << "Reflector()" << endl;
            Factory::getInstance().Register(name, objc);
        }
        virtual ~Reflector(){ cout << "~Reflector()" << endl; }
    
    };
    



    应用类

    class Derive : public Base
    {
    public:
        Derive(){ cout << "Derive()" << endl; }
        virtual ~Derive(){ cout << "~Derive()" << endl; }
        
        void print()
        {
            cout << "Derive print()" << endl;
        }
    };
    
    Base* CreateObject()
    {
        return new Derive;  
    } 
    // 通过 Reflector 构造函数向工厂类中注册
    Reflector reflector("Derive", CreateObject);
    

    同样通过定义宏的方式简化,注意因为Reflector不再维护应用类的信息,而只是单纯的做注册,每个应用类的 CreateObject 和 对应的 reflector 不再需要作为应用类的成员。 所以在定义 CreateObject 和 实例化 reflector时,需要加上应用类的特殊标识。 这里利用宏,将应用类的 className 拼接在对应的 CreateObject 和 reflector 后面:

    #define REGISTER(className) \
        Base* CreateObject##className() \
        { \
            return new className; \
        } \
        Reflector reflector##className(#className, CreateObject##className); \
    

    完整代码:
    reflect_2.h

    #ifndef _REFLECT_1_H_
    #define _REFLECT_1_H_
    
    #include <iostream>
    #include <map>
    
    using namespace std;
    
    // 支持反射的基类
    class Base
    {
    public:
        Base(){ cout << "Base()" << endl; }
        virtual ~Base(){ cout << "~Base()" << endl; }
        
        virtual void print(){
            cout << "Base print()" << endl;
        }
    };
    
    typedef Base* (*ObjectConstructor)();
    
    // 工厂类 
    // - 提供注册接口,注册子类的 Reflector 对象
    // - 提供返回创建对象接口,根据子类类名返回实例
    class Factory
    {
    private:
        Factory(){ cout << "Factory()" << endl; }
        
    public:
        ~Factory(){ cout << "~Factory()" << endl; }
        
    public:
        static Factory& getInstance();
        
        void Register(string className, ObjectConstructor objc);
        
        Base* getObject(string className);
    
    private:
        map<string, ObjectConstructor> objectMap;
    };
    
    // impl
    Factory& Factory::getInstance()
    {
        static Factory factory;
        return factory;
    }
    
    void Factory::Register(string className, ObjectConstructor m_objc)
    {
        if (m_objc)
        {
            objectMap.insert(map<string, ObjectConstructor>::value_type(className, m_objc));
        }
    }
    
    Base* Factory::getObject(string className)
    {
        map<string, ObjectConstructor>::const_iterator iter = objectMap.find(className);
        if (iter != objectMap.end())
        {
            return iter->second();
        }
    }
    
    // 实现反射的类 
    // - 构造时将自身的(实际上就是子类的) className 和 Reflector写入 map 中
    // - 回调函数实现返回子类的实例 
    class Reflector
    {
    public:
        Reflector(string name, ObjectConstructor objc)
        {
            cout << "Reflector()" << endl;
            Factory::getInstance().Register(name, objc);
        }
        virtual ~Reflector(){ cout << "~Reflector()" << endl; }
    
    };
    
    
    #define REGISTER(className) \
        Base* CreateObject##className() \
        { \
            return new className; \
        } \
        Reflector reflector##className(#className, CreateObject##className); \
    
    
    #endif
    



    reflect_2.cpp

    #include "reflect_2.h"
    
    #include <iostream>
    
    using namespace std;
    
    // 支持反射的子类
    class Derive : public Base
    {
    public:
        Derive(){ cout << "Derive()" << endl; }
        virtual ~Derive(){ cout << "~Derive()" << endl; }
        
        void print()
        {
            cout << "Derive print()" << endl;
        }
    };
    REGISTER(Derive);
    
    
    class Derive2 : public Base
    {
    public:
        void print()
        {
            cout << "Derive2 print()" << endl;
        }
    };
    REGISTER(Derive2);
    
    int main()
    {   
        Base* p = Factory::getInstance().getObject("Derive");
        if (p)
        {
            p->print();
        }
        delete p;
        
        Base* p2 = Factory::getInstance().getObject("Derive2");
        if (p2)
        {
            p2->print();
        }
        delete p2;
        
        return 0;
    }
    
    

    相关文章

      网友评论

          本文标题:C++ 简单工厂模式与反射机制

          本文链接:https://www.haomeiwen.com/subject/ketpzhtx.html