美文网首页
【Poco笔记】根据名字动态生成类对象实例

【Poco笔记】根据名字动态生成类对象实例

作者: 安安爸Chris | 来源:发表于2018-12-31 10:07 被阅读0次

    高级语言里如java有反射,可以根据类名动态生成类实例;也可以动态获取类成员变量和函数。

    Poco里是否有类似功能呢? 对于前者,根据类名动态生成类实例。Poco提供了类似的功能。

    它就是模板类DynamicFactory

    它的原理很简单,通过注册名字,将名字与类型储存在map中。使用的时候根据名字找寻对应的类型,然后生成该类型的实例。

    我们来看一下使用。 定义两个类A,B都集成基类Base

        class Base
        {
        public:
            Base()
            {
            }
            
            virtual ~Base()
            {
            }
        };
        
        class A: public Base
        {
        };
        
        class B: public Base
        {
        };
    

    使用Dynamic注册

        DynamicFactory<Base> dynFactory;
        
        dynFactory.registerClass<A>("A");
        dynFactory.registerClass<B>("B");
        
        assert (dynFactory.isClass("A"));
        assert (dynFactory.isClass("B"));
        
        assert (!dynFactory.isClass("C"));
    
        std::unique_ptr<A> a(dynamic_cast<A*>(dynFactory.createInstance("A")));
        std::unique_ptr<B> b(dynamic_cast<B*>(dynFactory.createInstance("B")));
    
        try{
            dynFactory.registerClass<A>("A");
            fail("already registered - must throw");
        }
        catch (Poco::ExistsException&)
        {
        }
        
        dynFactory.unregisterClass("B");
        assert (dynFactory.isClass("A"));
        assert (!dynFactory.isClass("B"));
    
        try
        {
            std::unique_ptr<B> b(dynamic_cast<B*>(dynFactory.createInstance("B")));
            fail("unregistered - must throw");
        }
        catch (Poco::NotFoundException&)
        {
        }
    

    DynamicFactory的模板是基类类型,注册时使用子类类型。


    看一下源码的实现原理。
    在DynamicFactory中定义了实现工厂的接口AbstractInstantiator,然后在map中存储名字和AbstractInstantiator键值对。就这么简单!

    template <class Base>
    class DynamicFactory
    {
    public:
    // 定义了抽象方法
    typedef AbstractInstantiator<Base> AbstractFactory
    
    
    private:
        typedef std::map<std::string, AbstractFactory*> FactoryMap;
        
        FactoryMap _map; // 基本原理就是将类名称和类型存储在map中
        mutable FastMutex _mutex;
    }
    

    那么AbstractFactory是什么呢?说白了,它就是一个接口,定义了行为。

    template <class Base>
    class AbstractInstantiator
    {
        // 通过该接口定义实现实例,返回基类指针
        virtual Base* createInstance() const = 0;
    }
    

    具体的类是Instantiator,跟AbstractFactory定义在一起。

    template <class C, class Base>
    class Instantiator: public AbstractInstantiator<Base>
    {
    public:
        // 哦,原来如此。就这么简单
        Base* createInstance() const
        {
            return new C;
        }
    }
    

    所以从源码上来看,DynamicFactory中的模板类跟注册类可以是继承关系,也可以是同一个类型。

    相关文章

      网友评论

          本文标题:【Poco笔记】根据名字动态生成类对象实例

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