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

时间:2017-11-23 23:36:42

标签: c++ static-polymorphism

我习惯使用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"
}

2 个答案:

答案 0 :(得分:2)

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

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

你现在缺少什么?

请考虑以下代码:

Base* base;

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

base->interface();

变量a的值仅在运行时已知,因此您只能对其使用动态多态。

如果它是静态多态性,你应该已经告诉了什么是派生类的类型。

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

这不允许您根据运行时上下文来决定它。

答案 1 :(得分:1)

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

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

注意:动态多态的开销非常小,在配置程序并查看开销很大之前,您不应该考虑它。这种情况很少发生。