我可以用静态多态实现动态多态的所有功能吗?

Posted

技术标签:

【中文标题】我可以用静态多态实现动态多态的所有功能吗?【英文标题】:Can I achieve all the functionality of dynamic polymorphism with static polymorphism? 【发布时间】:2017-11-23 23:36:42 【问题描述】:

我习惯使用dynamic polymorphism,一切正常,但在阅读了static polymorphism 之后,我得出结论,后者克服了动态的开销。

这里有一些动态多态的开销:

每次调用虚拟方法的额外间接(指针解引用)。

虚拟方法通常不能内联,这对一些小方法来说可能会造成很大的成本损失。

每个对象的附加指针。在当今流行的 64 位系统上,这是每个对象 8 个字节。对于携带少量数据的小对象,这可能是一个严重的开销。

谁能用一个非常简单的例子向我解释Static polymorphism。什么情况下我应该使用它而不是动态的?

我找到了这个例子,但很抱歉我不明白。看起来模棱两可:

#include <iostream>
using namespace std;

template <typename Child>
struct Base

    void interface()
    
        static_cast<Child*>(this)->implementation();
    
;

struct Derived : Base<Derived>

    void implementation()
    
        cerr << "Derived implementation\n";
    
;

int main()

    Derived d;
    d.interface();  // Prints "Derived implementation"

【问题讨论】:

"" - 假设您询问的是编译时与运行时多态性,那么“否”。 【参考方案1】:

我们先分析一下你发送的代码编译后会发生什么。编译器会生成两个类,在方法接口内部,它只会将指针移动到 Derived 对象所在的地址,并使用该指针调用方法实现。

所以现在我们唯一的开销是我们应该为每个派生类生成更多的类(我的意思是二进制代码)。

你现在缺少什么?

考虑以下代码:

Base* base;

if(a)
  base = new DerivedA;
else
  base = new DerivedB;

base->interface();

变量a的值只有在运行时才知道,所以只能对它使用动态多态性。

如果是静态多态,你应该告诉派生类的类型。

Base<DerivedA> * base;
Base<DerivedB> * base;

这不允许您决定,取决于运行时上下文。

【讨论】:

【参考方案2】:

静态多态是函数重载的替代名称。这是一个方便的功能,它可以让您避免仅仅为了获取一组替代参数而重命名函数。

当函数在运行时决定时,它与动态多态完全正交,动态多态是一种实际的调度机制。

注意:动态多态性的开销是如此之小,以至于在您分析程序并发现开销很大之前,您不应该考虑它。这种情况很少发生。

【讨论】:

谢谢。 static polymorphismcrtp 一样吗? @WonFeiHong 不,CRTP 是一个不相关的模式。静态多态(重载)只是一种语言特性。

以上是关于我可以用静态多态实现动态多态的所有功能吗?的主要内容,如果未能解决你的问题,请参考以下文章

什么是多态性

c++八股之多态(持续更新)

C++静态多态与动态多态的实现原理剖析

C++静态多态与动态多态的实现原理剖析

第十二章 多态性与抽象类

C++多态 --- 多态实现原理简析