14

利用可能な最も安全なC++キャストであるため、私はさまざまな感情を抱いてstatic_castいますが、同時に安全な変換と安全でない変換の両方を許可するため、実際に安全であるか、UBにつながる可能性があるか(キャスト時など)を判断するためのコンテキストを知る必要がありますサブクラスへ)。

では、なぜより安全な明示的なキャストがないのでしょうか。これが役立つ例です。COMでは、インターフェイスポインタをとして返す必要があるvoid** ppvため、明示的にキャストする必要があります

*ppv = (IInterface*) this;

その後、より安全なC++キャストに置き換えることが提案されました

*ppv = static_cast<IInterface*>(this);

しかし、ここでさえ作ることは理にかなっていstatic_castますか?thisから派生したクラスなIInterfaceので、簡単に書くことができます

IInterface* p = this; // implicit conversion to base, safe for sure
*ppv = p;

またはのようなヘルパーを使用します

template<class T, class U>
T implicit_cast(U p) { return p; }

*ppv = implicit_cast<IInterface*>(this);

それで、時々誤用されて、場合static_castによってはこれに置き換えることができる(すべきですか?)というのは本当ですか、それとも私は何かを逃していますか?implicit_cast

編集: COMでキャストが必要であることは知っていますが、必ずしもそうである必要はありませんstatic_cast。暗黙のキャストで十分です。

4

1 に答える 1

5

この特定のケースでは、キャスティングが上向きになることは常に知られているので、それstatic_castは完全に安全であるはずだと私は信じています。

を使用するimplicit_cast方がおそらく安全であり、暗黙的にキャストする基本クラスを明示的に選択できるように見えます(これは明らかにCOMに必要です)。

私はg++で簡単なテストを行いましたimplicit_castが、実際には、予想どおり、基本クラスごとに異なるアドレスが返されます。

ただし、最初の文に関しては、キャストが完了できない場合にnullを返すかスローするためdynamic_cast、実際には安全であると主張することに注意してください。static_cast対照的に、static_castは有効なポインタを返し、プログラムが将来のある時点で爆発し、元の不良キャストに接続されなくなるまで続行できます。

テストプログラム:

#include <iostream>

class B1
{
public:
    virtual ~B1() {}
};

class B2
{
public:
    virtual ~B2() {}
};

class Foo : public B1, public B2
{
};

template<class T, class U>
T implicit_cast(U p) { return p; }

int main()
{
    Foo* f = new Foo;
    void **ppv = new void*;

    *ppv = implicit_cast<B1*>(f);
    std::cout << *ppv << std::endl;;
    *ppv = implicit_cast<B2*>(f);
    std::cout << *ppv << std::endl;;

    return 0;
}
于 2011-02-10T14:42:59.407 に答える