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

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

图片[1]就去ID网【Poco笔记】根据名字动态生成类对象实例 – 简书就去ID网97ID网

安安爸Chris

2018.12.31 10:07:59字数 314阅读 242

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

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

它就是模板类DynamicFactory

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

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

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

使用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&)
    {
    }
4812162024283236404448525660646872768084889296100104108112116120124128132

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;
}
48121620242832364044485256

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

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

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

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

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

图片[2]就去ID网【Poco笔记】根据名字动态生成类对象实例 – 简书就去ID网97ID网

0人点赞图片[3]就去ID网【Poco笔记】根据名字动态生成类对象实例 – 简书就去ID网97ID网

图片[4]就去ID网【Poco笔记】根据名字动态生成类对象实例 – 简书就去ID网97ID网

图片[5]就去ID网【Poco笔记】根据名字动态生成类对象实例 – 简书就去ID网97ID网Poco C++

图片[6]就去ID网【Poco笔记】根据名字动态生成类对象实例 – 简书就去ID网97ID网

更多精彩内容,就在简书APP

图片[7]就去ID网【Poco笔记】根据名字动态生成类对象实例 – 简书就去ID网97ID网

“你的支持是我努力的动力,再小的力量也是一种支持,谢谢。”

还没有人赞赏,支持一下

图片[8]就去ID网【Poco笔记】根据名字动态生成类对象实例 – 简书就去ID网97ID网

安安爸Chris该博客记录工作和生活中的内容,个人兴趣部分请参考这里<a href=”https://link…

总资产37共写了3.9W字获得49个赞共54个粉丝

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    请登录后查看评论内容