Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中是否存在多态性的替代方案+;?_C++_Virtual Functions - Fatal编程技术网

C++ 在C+中是否存在多态性的替代方案+;?

C++ 在C+中是否存在多态性的替代方案+;?,c++,virtual-functions,C++,Virtual Functions,在这个问题中,建议使用动态多态性。然而,这种模式据说只对静态多态性有用。我所看到的设计似乎受到虚拟函数调用速度方面的阻碍,因为即使是2.5倍的加速也太棒了 所讨论的类很简单,可以完全内联编码,但是直到运行时才知道将使用哪些类。此外,他们可能会以任何顺序被锁链锁住,将绩效侮辱堆积在伤害之上 欢迎提出任何建议(包括在这种情况下如何使用CRTP) 编辑:谷歌搜索出现了函数模板。这些看起来很有希望。多态性字面上是指多种(多边形)形式(变形)。在静态类型语言(如C++)中,有三种类型的多态性 AdHoc多

在这个问题中,建议使用动态多态性。然而,这种模式据说只对静态多态性有用。我所看到的设计似乎受到虚拟函数调用速度方面的阻碍,因为即使是2.5倍的加速也太棒了

所讨论的类很简单,可以完全内联编码,但是直到运行时才知道将使用哪些类。此外,他们可能会以任何顺序被锁链锁住,将绩效侮辱堆积在伤害之上

欢迎提出任何建议(包括在这种情况下如何使用CRTP)


编辑:谷歌搜索出现了函数模板。这些看起来很有希望。

多态性字面上是指多种(多边形)形式(变形)。在静态类型语言(如C++)中,有三种类型的多态性

AdHoc多态性:这是C++中最好的函数和方法重载。根据对函数或方法签名的调用参数的编译时类型的匹配,相同的函数名将绑定到不同的方法 <>参数多态性:在C++中,这是模板和所有可以用它做的有趣的事情,例如CRTP、专业化、部分专业化、元编程等。同样,这种多态性,其中相同的模板名可以根据模板参数做不同的事情,是<强>编译时间<强>多态。
  • 子类型多态性:这就是我们在C++中听到多态性时的想法。这是派生类重写虚拟函数以专门化行为的地方。根据基类所指向的具体派生类型,指向基类的同一类型指针可以具有不同的行为。这是在C++中获得<强>运行时< /强>多态性的方法。
  • 如果直到运行时才知道将使用哪些类,则必须使用涉及虚拟函数调用的子类型多态性


    与静态绑定调用相比,虚拟方法调用的性能开销非常小。我强烈建议您看看这个问题的答案

    您可以选择Ole C路线并使用联合体。尽管这也可能很混乱。

    我同意m-sharp的观点,即您不会避免运行时多态性

    如果你看重的是优化而不是优雅,试着换一种说法

    void invoke_trivial_on_all(const std::vector<Base*>& v)
    {
      for (int i=0;i<v.size();i++)
        v[i]->trivial_virtual_method();
    }
    
    void调用所有(const std::vector&v)
    {
    对于(int i=0;iTrival_virtual_method();
    }
    
    有点像

    void invoke_trivial_on_all(const std::vector<Base*>& v)
    {
      for (int i=0;i<v.size();i++)
      {
        if (v[i]->tag==FooTag)
          static_cast<Foo*>(v[i])->Foo::trivial_virtual_method();
        else if (v[i]->tag==BarTag)
          static_cast<Bar*>(v[i])->Bar::trivial_virtual_method();
        else...
      }
    }
    
    void调用所有(const std::vector&v)
    {
    对于(int i=0;itag==FooTag)
    静态_cast(v[i])->Foo::tritile_virtual_method();
    else if(v[i]->tag==BarTag)
    静态_cast(v[i])->Bar::平凡的_虚拟_方法();
    其他的
    }
    }
    
    它并不漂亮,当然也不是OOP(更像是对旧的“C”的回归),但是如果虚拟方法足够简单,你应该得到一个没有调用的函数(取决于足够好的编译器和优化选项).使用dynamic_cast或typeid的变体可能更优雅/安全,但请注意,这些功能有其自身的开销,这可能与虚拟调用相当


    您最有可能从上面看到改进的地方是,如果某些类方法不是ops,它可以避免您调用它们,或者如果函数包含公共循环不变代码,并且优化程序成功地将其从循环中提升出来。

    我相信模板中的if语句可能会使这一混乱变得更干净。看起来还是有希望的。PLE如果使用static_cast而不是reinterpret_cast,则在某些情况下,后者会给出不正确的结果(在典型的实现中,如果Foo或Bar有多个基类,并且基类不是第一个基类,则是一个示例)。否则,链很可能会变慢。分支相当昂贵。不仅如此,还要将它们链起来,这意味着你有O(N)时间关键部分的行为…更好的比较应该是切换和虚拟函数调用。即使如此,速度也应该是相似的…我将此作为“洋葱”读了三遍,只能想象您的“混乱”工作流涉及到什么。