c ++自动工厂注册派生类型 [英] c++ automatic factory registration of derived types

查看:127
本文介绍了c ++自动工厂注册派生类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

像许多在我之前,我想让我的派生类型自动注册我的工厂。

Like many before me, I'm trying so get my derived types to automatically register with my factory. I read through many question and tried to focus on what I didn't find there.

除了自动注册之外,我一切都运行良好。

I've got everything running nicely except the automatic registration.

我的目标:


  1. 自动注册我的基础基本

  1. 只有我标记为可注册的类

  2. 子类基本

    • 例如:基本 - >设备 - >相机 - > 网络摄像头 http://stackoverflow.com/questions/6399804/automatic-static-invocation-of-derived-types\">这个问题困难

  1. only classes I mark as registrable
  2. not only direct sub-classes of Base
    • ex: Base -> Device -> Camera -> Webcam
    • this would make using the CRTP like described in this question dificult


  • 对我想要注册的类别进行最小更改

  • 例如注册商类,而不是宏

    • -of-derived-types>此问题,但我不确定这是否依赖于 CRTP

    • minimal changes to the classes I want registered - dummies proof
    • would prefer using a registrator class than macros
      • like in this question, but I'm not sure if this is dependent on CRTP
      • 我有什么: >

        What I have:

        template <class T>
        class abstract_factory
        {
            public:
                template < typename Tsub > static void register_class();
                static T* create( const std::string& name );
            private:
                // allocator<T> is a helper class to create a pointer of correct type
                static std::map<std::string, boost::shared_ptr<allocator<T> > > s_map;
        };
        




        • 模板抽象工厂, std :: string 作为键类型

        • 抽象工厂具有所有成员和方法静态

        • 使用 typeid (注册时不需要文本名称)自动恢复名称

        • 通过调用注册: abstract_factory< Base> :: register_class< ; MyDerived>();

          • templated abstract factory, with std::string as key type
          • abstract factory has all members and methods static
          • class name is recovered automatically with typeid (no need for text name when registering)
          • registration by calling: abstract_factory<Base>::register_class<MyDerived>();
          • t知道如何正确):


            • 注册商< Derived& class :在 Derived.cpp 中静态实例化的templated类,应该调用 abstract_factory :: register_class< Derived> 在它的构造函数

              • 从不调用或实例化

              • 如果我做一个中导出 main()这个工作 - > kinda失败的目的

              • registrator<Derived> class: templateded class that is instantiated statically in Derived.cpp and should call abstract_factory::register_class<Derived>() in it's constructor
                • never gets called or instantiated
                • if I make an instance of Derived in main() this works -> kinda defeats the purpose though

                可以使用任何大小的建议。

                Could use any advice, large or small, thanx.

                推荐答案

                我使用一个单独的成员注册,基本上:

                I use a singleton with a member for registration, basically:

                template< typename KeyType, typename ProductCreatorType >
                class Factory
                {
                    typedef boost::unordered_map< KeyType, ProductCreatorType > CreatorMap;
                    ...
                };
                

                使用Loki我可以按照以下方式操作:

                Using Loki I then have something along these lines:

                 typedef Loki::SingletonHolder< Factory< StringHash, boost::function< boost::shared_ptr< SomeBase >( const SomeSource& ) > >, Loki::CreateStatic > SomeFactory;
                

                注册通常使用以下宏来完成:

                Registration is usually done using a macro such as:

                #define REGISTER_SOME_FACTORY( type ) static bool BOOST_PP_CAT( type, __regged ) = SomeFactory::Instance().RegisterCreator( BOOST_PP_STRINGIZE( type ), boost::bind( &boost::make_shared< type >, _1 ) );
                

                此设置具有许多优点:


                • 适用于例如boost :: shared_ptr<>。

                • 不需要为所有注册需求维护一个大文件。

                • 非常灵活的创作者,任何东西都很多。

                • 宏包括最常见的用例, b $ b
                • Works with for example boost::shared_ptr<>.
                • Does not require maintaining a huge file for all the registration needs.
                • Is very flexible with the creator, anything goes pretty much.
                • The macro covers the most common use case, while leaving the door open for alternatives.

                然后在.cpp文件中调用宏就足以在静态初始化过程中获取在启动时注册的类型。这工作dandy保存,当类型注册是静态库的一部分,在这种情况下,它不会包括在您的二进制文件。编译注册作为库的一部分,我已经看到工作的唯一解决方案是有一个巨大的文件,作为某种初始化例程的一部分显式地注册。相反我现在做的是有一个客户端文件夹与我的lib,用户包括作为二进制构建的一部分。

                Invoking the macro in the .cpp file is then enough to get the type registered at start up during static initialization. This works dandy save for when the type registration is a part of a static library, in which case it won't be included in your binary. The only solutions which compiles the registration as a part of the library which I've seen work is to have one huge file that does the registration explicitly as a part of some sort of initialization routine. Instead what I do nowadays is to have a client folder with my lib which the user includes as a part of the binary build.

                从你的需求列表我相信这满足一切都保存为使用注册商类。

                From your list of requirements I believe this satisfies everything save for using a registrator class.

                这篇关于c ++自动工厂注册派生类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆