【问题标题】:c++ templates, virtual funcs, empty baseC++ 模板,虚函数,空基
【发布时间】:2013-11-19 21:07:10
【问题描述】:

仍然掌握 c++ 类的窍门,我想知道实现这一点的最高效的运行时方法是什么:

我有一个派生类,我想实例化一次(在编译时已知),但我想将指针类型转换为基类指针并将其传递给我的程序的其余部分以使用。这样,如果我有一个未来的项目我想将实例从 animal.dog 更改为 animal.cat,我的代码的所有其他部分仍然能够调用方法 animalPtr->eat(),但实际行为将特定于狗或猫。我只会有一个 animal.dog 或 animal.cat 的实例,而且我永远不会有一个基类动物的实例。

也许我刚才描述的正是我需要做的,但我阅读了一些关于让基类“动物”使用虚函数与​​让基类成为模板类的利弊的在线争论(不完全确定在这种情况下如何将其制成模板......对我来说,模板类看起来像是用于为成员创建通用数据类型,但这不是我在这里需要的)。

有什么帮助吗?请记住,速度性能对我来说是最高优先级。

【问题讨论】:

  • 代替多态性(即使用继承和虚函数),您也许可以使用PIMPL idiom 来隐藏实现。
  • 请记住,速度-性能对我来说是最高优先级 大多数情况下并非如此。好和更好之间的性能差异可能不值得为实现 更好 付出代价。构建一些简单的、有效的并且不可怕的东西,然后决定你是否需要额外的性能。几微秒的开发时间值得吗?

标签: c++ function templates virtual


【解决方案1】:

使用虚函数是解决这个问题的面向对象的方法。使用通常的虚函数实现,它增加了另一个指针间接并使得内联变得不可能,所以如果你真的,真的,真的有性能问题并且函数很小并且在紧密循环中被调用数百万次,那么你可能会遇到性能问题。

使用虚函数方法开始。如果这是一个问题(并且您已经测量出这确实是分析器的问题),那么您可以考虑将事情更改为可能更有效的基于模板的方法。

【讨论】:

    【解决方案2】:

    可以通过模板化基类来实现您想要的不带虚拟功能的功能:

    template<class Parent>
    class BASE {
    public:
        BASE();
        virtual ~BASE();
        void func() {
             reinterpret_cast<Parent*>(this)->func(); // call parent func
             // or
             (Parent*)(this)->func();      
        }
    };
    

    您可以稍后将 BASE 类键入定义为普通类名:

    typedef BASE<specific_Parent> myBASE;
    

    【讨论】:

      【解决方案3】:

      在我看来,您正在尝试在运行时多态性和编译时多态性之间做出决定。如果您确实需要运行时多态性,则必须使用虚函数。但是如果你真的不需要运行时多态,你可以使用CRTP来实现编译时多态。

      这是一个非常原始的示例,说明了编译时多态性 (code on ideone.com):

      #include <iostream>
      
      namespace so {
      template<typename _t_derived_>
      class _animal_ {
      private:
          using _derived_ = _t_derived_;
      public:
          void eat() const {
              static_cast<_derived_ const *>(this)->eat_impl();
          }
      };
      
      class _dog_: public _animal_<_dog_> {
          friend class _animal_<_dog_> ;
      private:
          using _base_ = _animal_<_dog_>;
      protected:
          void eat_impl() const {
              std::cout << "dog's eating." << std::endl;
          }
      };
      
      class _cat_: public _animal_<_cat_> {
          friend class _animal_<_cat_> ;
      private:
          using _base_ = _animal_<_cat_>;
      protected:
          void eat_impl() const {
              std::cout << "cat's eating." << std::endl;
          }
      };
      
      template<typename _t_animal_>
      void feed(_t_animal_ const & _animal) {
          std::cout << "feeding an animal: ";
          _animal.eat();
      }
      } // namespace so
      
      int main() {
          so::_dog_ dog_;
          so::_cat_ cat_;
      
          so::feed(dog_);
          so::feed(cat_);
      
          return (0);
      }
      

      程序输出:

      feeding an animal: dog's eating.
      feeding an animal: cat's eating.
      

      【讨论】:

        猜你喜欢
        • 2017-06-10
        • 2014-08-16
        • 2018-02-01
        • 2013-06-11
        • 2017-06-28
        • 2012-07-03
        • 2021-11-08
        • 2010-11-19
        相关资源
        最近更新 更多