我可以用静态多态实现动态多态的所有功能吗?
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 polymorphism
和 crtp
一样吗?
@WonFeiHong 不,CRTP 是一个不相关的模式。静态多态(重载)只是一种语言特性。以上是关于我可以用静态多态实现动态多态的所有功能吗?的主要内容,如果未能解决你的问题,请参考以下文章