我习惯使用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"
}
答案 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)
静态多态性是函数重载的替代名称。这是一个方便的功能,它可以让您避免重命名函数只是为了采取一组替代参数。
它与动态多态完全正交,动态多态是一种实际的调度机制,在运行时决定函数。
注意:动态多态的开销非常小,在配置程序并查看开销很大之前,您不应该考虑它。这种情况很少发生。