• <tfoot id='WFvfC'></tfoot>
    <legend id='WFvfC'><style id='WFvfC'><dir id='WFvfC'><q id='WFvfC'></q></dir></style></legend>

      • <bdo id='WFvfC'></bdo><ul id='WFvfC'></ul>

      <i id='WFvfC'><tr id='WFvfC'><dt id='WFvfC'><q id='WFvfC'><span id='WFvfC'><b id='WFvfC'><form id='WFvfC'><ins id='WFvfC'></ins><ul id='WFvfC'></ul><sub id='WFvfC'></sub></form><legend id='WFvfC'></legend><bdo id='WFvfC'><pre id='WFvfC'><center id='WFvfC'></center></pre></bdo></b><th id='WFvfC'></th></span></q></dt></tr></i><div id='WFvfC'><tfoot id='WFvfC'></tfoot><dl id='WFvfC'><fieldset id='WFvfC'></fieldset></dl></div>

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

        生成没有虚函数的接口?

        时间:2023-10-07

          • <bdo id='ju9d3'></bdo><ul id='ju9d3'></ul>

                  <tbody id='ju9d3'></tbody>
                <legend id='ju9d3'><style id='ju9d3'><dir id='ju9d3'><q id='ju9d3'></q></dir></style></legend>
              • <i id='ju9d3'><tr id='ju9d3'><dt id='ju9d3'><q id='ju9d3'><span id='ju9d3'><b id='ju9d3'><form id='ju9d3'><ins id='ju9d3'></ins><ul id='ju9d3'></ul><sub id='ju9d3'></sub></form><legend id='ju9d3'></legend><bdo id='ju9d3'><pre id='ju9d3'><center id='ju9d3'></center></pre></bdo></b><th id='ju9d3'></th></span></q></dt></tr></i><div id='ju9d3'><tfoot id='ju9d3'></tfoot><dl id='ju9d3'><fieldset id='ju9d3'></fieldset></dl></div>
                  <tfoot id='ju9d3'></tfoot>
                • <small id='ju9d3'></small><noframes id='ju9d3'>

                • 本文介绍了生成没有虚函数的接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我正在编写一个游戏引擎,并且我为对象设置了这个类:

                  I'm coding a game engine and I have this class set up for objects:

                  class SceneManager //controls everything in the "world" game
                  {
                      public:
                          void Add(SceneObject* object); //adds to the vector
                      private:
                          vector<SceneObject*> _worldObjects; //the vector that contains all of them
                  }
                  

                  我在游戏中工作的所有类都继承自 SceneObject:

                  And all classes I work on the game inherit from SceneObject:

                  class SceneObject
                  {
                      public: 
                          virtual void Draw() = 0;
                  }
                  
                  class Image : public SceneObject
                  { }
                  class Sprite : public SceneObject
                  { }
                  class Model3D : public SceneObject
                  { }
                  

                  所以我知道我可以为向量中的所有对象调用 Draw().但我一直在进行优化,我试图摆脱所有继承和虚函数,并改用组合,因为它们不能内联,并且在对每个对象执行时似乎是一个主要的性能问题基础.

                  So I know I can call Draw() for all objects in my vector. But I've been working on optimizations and I'm trying to get rid of all inheritance and virtual functions, and use composition instead, since they can't be inlined and seems to be a major performance issue when performed on a per-object basis.

                  我正在寻找一些 C++ 技术,我可以使用它来将一堆 SceneObjects 存储在我的向量中,然后对其调用 Draw() 并正确地绘制与其相关的对象.这也适用于我用作虚拟的 Update() 函数.

                  I'm looking for some C++ technique that I can use to be able to store a bunch of SceneObjects in my vector, and then call Draw() on it and it properly draws the object related to it. This will also work for the Update() function I'm using as virtual.

                  所以这段代码:

                  void SceneManager::Add(SceneObject* object)
                  {
                      _worldObjects.push_back(object);
                  }
                  void SceneManager::DrawTheWorld()
                  {
                      for(unsigned int i = 0; i < _worldObjects.size(); i++)
                      {
                          _worldObjects[i]->Draw(); //SceneObject's being called
                      }
                  }
                  

                  ...会变成:

                  void SceneManager::Add(Image* image)
                  {
                      SceneObject* object = new SceneObject();
                      //link object to image somehow, tried to use it as a member of image
                      _worldObjects.push_back(object);
                  }
                  void SceneManager::DrawTheWorld()
                  {
                      for(unsigned int i = 0; i < _worldObjects.size(); i++)
                      {
                          //_worldObjects[i]->
                          //I need somehow to be able to get the pointer back to the original class
                          //It can be an image, sprite, model3d, anything
                      }
                  }
                  

                  我不认为如果我添加一个开关或 if/elses 并删除虚拟我会获得任何性能,所以我试图弄清楚是否有一种干净的方法来处理这个问题.

                  I don't think if I add a switch or if/elses and removing the virtual I'd gain any performance, so I'm trying to figure if there's a clean way to deal with this.

                  有什么想法吗?

                  推荐答案

                  您可以使用自由函数为对象的 drawable 方面建模:

                  You can use free functions to model the drawable aspect of your objects:

                  #include <iostream>
                  
                  class Image { };
                  class Sprite { };
                  class Model3D { };
                  
                  namespace draw_aspect
                  {
                      void draw(Image const& image)     { std::cout << "drawing image
                  ";   } 
                      void draw(Sprite const& sprite)   { std::cout << "drawing sprite
                  ";  } 
                      void draw(Model3D const& model3D) { std::cout << "drawing model3D
                  "; } 
                  }
                  

                  <小时>

                  现在,要么使用三个单独的向量(这可能是最佳的,取决于集合中对象之间的排序关系?),或者考虑使用变体类型向量:


                  Now, either use three separate vectors (this could well be most optimal, depending on the ordering relationship between the objects across collections?), or consider a variant type vector:

                  #include <boost/variant.hpp>
                  using SceneObject = boost::variant<Image, Sprite, Model3D>;
                  
                  namespace draw_aspect {    
                  
                      struct draw_visitor : boost::static_visitor<> {
                          template <typename T> void operator()(T const& t) const { draw(t); }
                      };
                  
                      void draw(SceneObject const& sobj) { 
                          static const draw_visitor _vis;
                          boost::apply_visitor(_vis, sobj);
                      }
                  }
                  

                  后者的完整概念证明:在 Coliru 上直播

                  A complete proof of concept of the latter: Live on Coliru

                  #include <vector>
                  
                  class SceneManager //controls everything in the "world" game
                  {
                      public:
                          void Add(SceneObject v) { _worldObjects.emplace_back(std::move(v)); }
                          friend void draw(SceneManager const& sm) { return sm.draw(); }
                      private:
                          void draw() const {
                              for(auto& sobj : _worldObjects)
                                  draw_aspect::draw(sobj);
                          } 
                          std::vector<SceneObject> _worldObjects; //the vector that contains all of them
                  };
                  
                  int main()
                  {
                      SceneManager sman;
                  
                      sman.Add(Image());
                      sman.Add(Sprite());
                      sman.Add(Model3D());
                      sman.Add(Image());
                  
                      draw(sman);
                  }
                  

                  输出

                  drawing image
                  drawing sprite
                  drawing model3D
                  drawing image
                  

                  2.单独的集合

                  使用单独向量的替代方法:在 Coliru 上直播

                  class SceneManager //controls everything in the "world" game
                  {
                      public:
                          void Add(Image v)   { _images  .emplace_back(std::move(v)); }
                          void Add(Sprite v)  { _sprites .emplace_back(std::move(v)); }
                          void Add(Model3D v) { _model3Ds.emplace_back(std::move(v)); }
                  
                          friend void draw(SceneManager const& sm) { return sm.draw(); }
                      private:
                          void draw() const {
                              for(auto& sobj : _images)   draw_aspect::draw(sobj);
                              for(auto& sobj : _sprites)  draw_aspect::draw(sobj);
                              for(auto& sobj : _model3Ds) draw_aspect::draw(sobj);
                          } 
                          std::vector<Image> _images;
                          std::vector<Sprite> _sprites;
                          std::vector<Model3D> _model3Ds;
                  };
                  
                  int main()
                  {
                      SceneManager sman;
                  
                      sman.Add(Image());
                      sman.Add(Sprite());
                      sman.Add(Model3D());
                      sman.Add(Image());
                  
                      draw(sman);
                  }
                  

                  注意输出是不同的(排序):

                  drawing image
                  drawing image
                  drawing sprite
                  drawing model3D
                  

                  这篇关于生成没有虚函数的接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:单例实例声明为 GetInstance 方法的静态变量,它是 下一篇:boost::asio 和活动对象

                  相关文章

                  最新文章

                • <legend id='WZyih'><style id='WZyih'><dir id='WZyih'><q id='WZyih'></q></dir></style></legend>

                  <tfoot id='WZyih'></tfoot>

                      <bdo id='WZyih'></bdo><ul id='WZyih'></ul>

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

                      <i id='WZyih'><tr id='WZyih'><dt id='WZyih'><q id='WZyih'><span id='WZyih'><b id='WZyih'><form id='WZyih'><ins id='WZyih'></ins><ul id='WZyih'></ul><sub id='WZyih'></sub></form><legend id='WZyih'></legend><bdo id='WZyih'><pre id='WZyih'><center id='WZyih'></center></pre></bdo></b><th id='WZyih'></th></span></q></dt></tr></i><div id='WZyih'><tfoot id='WZyih'></tfoot><dl id='WZyih'><fieldset id='WZyih'></fieldset></dl></div>