質問

私は、静的なキャストを使用して継承階層をナビゲートすると、ダイナミックキャストを使用するよりも効率的であることを言及する++ Cで一冊の本を見ます。

例:

#include <iostream>
#include <typeinfo>

using namespace std;

class Shape { public: virtual ~Shape() {}; };
class Circle : public Shape {};
class Square : public Shape {};
class Other {};

int main() {
    Circle c;

    Shape* s = &c; // Upcast: normal and OK

    // More explicit but unnecessary:
    s = static_cast<Shape*>(&c);
    // (Since upcasting is such a safe and common
    // operation, the cast becomes cluttering)

    Circle* cp = 0;
    Square* sp = 0;

    // Static Navigation of class hierarchies
    // requires extra type information:
    if(typeid(s) == typeid(cp)) // C++ RTTI
        cp = static_cast<Circle*>(s);
    if(typeid(s) == typeid(sp))
        sp = static_cast<Square*>(s);
    if(cp != 0)
        cout << "It's a circle!" << endl;
    if(sp != 0)
        cout << "It's a square!" << endl;

    // Static navigation is ONLY an efficiency hack;
    // dynamic_cast is always safer. However:
    // Other* op = static_cast<Other*>(s);
    // Conveniently gives an error message, while
    Other* op2 = (Other*)s;
    // does not
} ///:~

しかしながら、動的キャスト及びスタティックキャスト(上記実装される)の両方を必要とRTTIが機能するようなナビゲーションのために有効。これは、動的キャストが多型(すなわち、基底クラスを有する少なくとも一つの仮想関数)とクラス階層を必要とするだけということです。
静的なキャストについては、この効率のゲインはどこから来るのでしょうか? この本は、動的キャストは、タイプセーフなダウンキャストを行うための好ましい方法であることを言及しています。

役に立ちましたか?

解決

static_castそれ自体の必要はありませんRTTI - typeidん(dynamic_castがそうであるように)、それは完全に別の問題です。ほとんどのキャストはちょうど「私は私がやっているものを知って、私を信じて」コンパイラを言っている - dynamic_castは例外で、それは実行時にチェックし、おそらく失敗するようにコンパイラに要求します。それはすぐそこに大きなパフォーマンスの違いです!

他のヒント

これのの可能な場合は、すべてのタイプに切り替え避けるために、より良いの多くの。これは通常、異なるサブタイプのために異なる方法で実装される仮想メソッドに関連するコードを移動することによって行われます:

class Shape {
public:
    virtual ~Shape() {};
    virtual void announce() = 0;  // And likewise redeclare in Circle and Square.
};

void Circle::announce() {
    cout << "It's a circle!" << endl;
}

void Square::announce() {
    cout << "It's a square!" << endl;
}

// Later...
s->announce();

あなたが変更できないことを、既存の継承階層を使用している場合は、調査ビジタータイプスイッチングをより拡張可能な代替のためのパターン

詳細情報:static_castはRTTIを必要としませんが、それは未定義の動作につながる、危険なことができます使用してダウンキャストが(例えばクラッシュ)。それをチェックしRTTI情報を(したがってが必要)のでdynamic_castは、安全ではなく遅いです。それは静かにstatic_castは、コンパイル時エラーが発生したオブジェクトです完全に無関係の種類、全体にキャストされますので、古いCスタイルのキャストはさらに危険なstatic_castよります。

静的キャスト(およびtypeidをチェック)して、あなたがすることはできません。のダウンキャストの(父へ祖父からあなたが意気消沈することはできません祖父から父の派生から子導出し、)中間型への使用がもう少し限定されています。 typeidのチェックなしにはstatic_castをもパフォーマンスのために正確さを犠牲にされ、その後、あなたは彼らの言うことを知ってます:

の彼人犠牲正確性、パフォーマンスのために、どちらも

値しありません

次に、もちろん、あなたはいくつかのCPU命令の絶望的な必要としている状況があり、改善を探すためにどこにもあり、あなたがやっていることで、実際に安全であり、あなたはmeassuredている(右?)そのゲイン性能への唯一の場所の代わりのdynamic_castをstatic_castを使用している...そして、あなたがあなたのデザイン、またはあなたのアルゴリズムを手直しや、より良いハードウェアを取得する必要があります知っています。

あなたはRTTI +はstatic_castを使用することによって課す制限は、あなたがわずか数CPU命令を得るために、このトリックを使用しているすべての場所を作り直すことなく、後で新しい派生クラスを使用してコードを拡張することができませんということです。自分自身を再加工することは、おそらくより多くの時間あなたが取得したCPU時間よりも(より高価であるエンジニアリング時間を)取ること。 、任意の割合で、ダウンキャストに捧げた時間が顕著である場合j_random_hackerが示唆するように、そして、あなたの設計を手直し、それはデザインと性能の両方を向上させます。

あなたはタイプIDチェックを行っていなかったとキャストが成功しなかった場合、

dynamic_castはNULLを返します。 static_castは成功する(そして、このような最終的なクラッシュなど、未定義の動作につながる)でしょう。それはおそらく速度差です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top