2017-11-23 14 views
-1

私は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

"静的多型を使用して動的多型のすべての機能を達成できますか?" - コンパイル時と実行時の多型を尋ねると仮定すると、「いいえ」と表示されます。 –

答えて

2

まず、送信したコードをコンパイルした後に起こることを分析しましょう。コンパイラは2つのクラスを生成し、メソッドインタフェースの内部では、Derivedのオブジェクトがあるアドレスへのポインタを移動し、そのポインタでメソッドの実装を呼び出します。

これでオーバーヘッドが増えました。派生クラスごとに、より多くのクラスを生成する必要があります(私はバイナリコードを意味します)。

あなたは今何が欠けていますか?

Base* base; 

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

base->interface(); 

変数aの値は、実行時にのみ知られているので、あなたはそれだけのために、動的ポリモーフィズムを使用することができます。

は、次のコードを考えてみましょう。

静的多型であれば、派生クラスのタイプを教えてください。

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

これは、ランタイムコンテキストに応じて決定できません。

1

静的多型は、関数のオーバーロードの代替名です。これは便宜的な機能であり、単にパラメータの代替セットを取るために関数の名前を変更することを避けることができます。

実行時に関数が決定されると、実際のディスパッチ機構である動的多型に完全に直交します。

注:動的多態性のオーバーヘッドは非常に小さいので、プログラムをプロファイルしてオーバーヘッドが重要であることを確認するまで考慮しないでください。これは非常にまれに起こります。

+0

ありがとうございます。 'static polymorphism'は' crtp'と同じですか? – WonFeiHong

+0

@WonFeiHongいいえ、CRTPは無関係のパターンです。静的多型(オーバーロード)は単なる言語機能です。 – dasblinkenlight

関連する問題