<bdo id='5dTW5'></bdo><ul id='5dTW5'></ul>
    1. <tfoot id='5dTW5'></tfoot>
      <legend id='5dTW5'><style id='5dTW5'><dir id='5dTW5'><q id='5dTW5'></q></dir></style></legend>
    2. <i id='5dTW5'><tr id='5dTW5'><dt id='5dTW5'><q id='5dTW5'><span id='5dTW5'><b id='5dTW5'><form id='5dTW5'><ins id='5dTW5'></ins><ul id='5dTW5'></ul><sub id='5dTW5'></sub></form><legend id='5dTW5'></legend><bdo id='5dTW5'><pre id='5dTW5'><center id='5dTW5'></center></pre></bdo></b><th id='5dTW5'></th></span></q></dt></tr></i><div id='5dTW5'><tfoot id='5dTW5'></tfoot><dl id='5dTW5'><fieldset id='5dTW5'></fieldset></dl></div>
    3. <small id='5dTW5'></small><noframes id='5dTW5'>

      在对象工厂中注册对象创建者

      Register an object creator in object factory(在对象工厂中注册对象创建者)
      <tfoot id='rHfoO'></tfoot>
      <i id='rHfoO'><tr id='rHfoO'><dt id='rHfoO'><q id='rHfoO'><span id='rHfoO'><b id='rHfoO'><form id='rHfoO'><ins id='rHfoO'></ins><ul id='rHfoO'></ul><sub id='rHfoO'></sub></form><legend id='rHfoO'></legend><bdo id='rHfoO'><pre id='rHfoO'><center id='rHfoO'></center></pre></bdo></b><th id='rHfoO'></th></span></q></dt></tr></i><div id='rHfoO'><tfoot id='rHfoO'></tfoot><dl id='rHfoO'><fieldset id='rHfoO'></fieldset></dl></div>
      • <legend id='rHfoO'><style id='rHfoO'><dir id='rHfoO'><q id='rHfoO'></q></dir></style></legend>

          <small id='rHfoO'></small><noframes id='rHfoO'>

                <tbody id='rHfoO'></tbody>

              • <bdo id='rHfoO'></bdo><ul id='rHfoO'></ul>
              • 本文介绍了在对象工厂中注册对象创建者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                我有一个方便的对象工厂模板,它可以通过类型 ID 名称创建对象.实现非常明显:ObjectFactory 包含从 std::string 到对象创建者函数的映射.那么所有要创建的对象都要在这个工厂注册.

                I have the convenient object factory template that creates objects by their type id names. The implementation is pretty obvious: ObjectFactory contains the map from std::string to object creator function. Then all objects to be created shall be registered in this factory.

                我使用以下宏来做到这一点:

                I use the following macro to do that:

                #define REGISTER_CLASS(className, interfaceName) 
                   class className; 
                   static RegisterClass<className, interfaceName> regInFactory##className; 
                   class className : public interfaceName
                

                RegisterClass 在哪里

                   template<class T, class I>
                   struct RegisterClass
                   {
                      RegisterClass()
                      {
                         ObjectFactory<I>::GetInstance().Register<T>();
                      }
                   };
                

                用法

                class IFoo
                {
                public:
                   virtual Do() = 0;
                   virtual ~IFoo() {}
                }
                
                REGISTER_CLASS(Foo, IFoo)
                {
                   virtual Do() { /* do something */ }
                }
                
                REGISTER_CLASS(Bar, IFoo)
                {
                   virtual Do() { /* do something else */ }
                }
                

                在工厂中同时定义和注册类.

                Classes are defined and registered in factory simultaneously.

                问题在于 regInFactory... 静态对象是在 .h 文件中定义的,因此它们将被添加到每个翻译单元中.同一个对象创建者会被多次注册,更重要的是会有很多静态存储时长的冗余对象.

                The problem is that regInFactory... static objects are defined in .h files, so they will be added to every translation unit. The same object creator will be registered several times, and, more important, there will be a lot of redundant objects with static storage duration.

                有什么办法可以做到如此优雅的注册(不是复制/粘贴类和接口名称),但又不会在全球范围内传播冗余的静态对象?

                Is there any way to do such elegant registration (not to copy/paste class and interface names), but do not spread redundant static objects around the globe?

                如果一个好的解决方案需要一些 VC++ 特定的扩展(不符合 C++ 标准),我会接受.

                If a good solution needs some VC++ specific extensions (not conforming to C++ standard), I will be OK with that.

                推荐答案

                所以你想把变量定义放在头文件中?有一种可移植的方式:模板类的静态变量.所以我们得到:

                So you want to put variables definitions in header file? There is a portable way: static variables of template classes. So we get:

                template <typename T, typename I>
                struct AutoRegister: public I
                {
                    // a constructor which use ourRegisterer so that it is instantiated; 
                    // problem catched by bocco
                    AutoRegister() { &ourRegisterer; } 
                private:
                    static RegisterClass<T, I> ourRegisterer;
                };
                
                template <typename T, typename I>
                RegisterClass<T, I> AutoRegister<T, I>::ourRegisterer;
                
                class Foo: AutoRegister<Foo, IFoo>
                {
                public:
                    virtual void Do();         
                };
                

                请注意,我保留了 IFoo 非虚拟的继承.如果存在多次从该类继承的风险,则它应该是虚拟的.

                Note that I've kept the inheritance of IFoo non virtual. If there is any risk of inheriting from that class multiple times, it should be virtual.

                这篇关于在对象工厂中注册对象创建者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                Consistent pseudo-random numbers across platforms(跨平台一致的伪随机数)
                Vary range of uniform_int_distribution(改变uniform_int_distribution的范围)
                What is a seed in terms of generating a random number?(就生成随机数而言,种子是什么?)
                Is 1.0 a valid output from std::generate_canonical?(1.0 是 std::generate_canonical 的有效输出吗?)
                Getting big random numbers in C/C++(在 C/C++ 中获取大随机数)
                What is the best way to generate random numbers in C++?(在 C++ 中生成随机数的最佳方法是什么?)
                1. <i id='xIHHe'><tr id='xIHHe'><dt id='xIHHe'><q id='xIHHe'><span id='xIHHe'><b id='xIHHe'><form id='xIHHe'><ins id='xIHHe'></ins><ul id='xIHHe'></ul><sub id='xIHHe'></sub></form><legend id='xIHHe'></legend><bdo id='xIHHe'><pre id='xIHHe'><center id='xIHHe'></center></pre></bdo></b><th id='xIHHe'></th></span></q></dt></tr></i><div id='xIHHe'><tfoot id='xIHHe'></tfoot><dl id='xIHHe'><fieldset id='xIHHe'></fieldset></dl></div>

                  <small id='xIHHe'></small><noframes id='xIHHe'>

                    <tbody id='xIHHe'></tbody>
                    <legend id='xIHHe'><style id='xIHHe'><dir id='xIHHe'><q id='xIHHe'></q></dir></style></legend>

                        <bdo id='xIHHe'></bdo><ul id='xIHHe'></ul>
                          <tfoot id='xIHHe'></tfoot>