1

T *ポインタが指すオブジェクトが本当にTオブジェクトなのか、それとも他の無関係なタイプなのかを判断しようとしています。dynamic_castを試しましたが、役に立たないわけではありません。有効なTオブジェクトを指していないことが明らかな場合でも、nullではなくポインタ自体を返します。

Object* garbage = reinterpret_cast<Object*>(0x12345678);
if( dynamic_cast<Object*>(garbage) == NULL ){
    cout << "Expected behaviour (by me)" << endl;
}else{
    cout << "You've got to be kidding me" << endl;
}

これ、または他の解決策の回避策はありますか?dynamic_castが役に立たない前にvoid*とchar*にキャストしようとしましたが、サブクラスも受け入れたいので、typeidも十分ではありません。

いくつかのコンテキスト:とのような異なる種類の配列間の浅い変換を実装するカスタム配列クラスを作成しています。たとえば、すべての要素アクセスで動的型チェックを実行することにより、最小限の型の安全性を保証したいと思いますArray<Object*>Array<String*>

#define DEBUG
Array<String*> v(10);
Array<Object*> o = v;
o[0] = new Integer(1);      //  this is technically illegal but no idea how to check
//Array<String*> w = o;     //  this fails with an exception
String* str = v[0];         //  but this should fail horribly as well
cout << str << endl;

Object *にキャストしてから、Object *の型チェックを行うことは多くの場合に機能しますが、の場合は失敗します。ただし、を使用せずにArray<Object*>Object以外のものをに挿入できるかどうかはわかりません。Array<Object*>reinterpret_cast。

4

4 に答える 4

1

あなたの例に基づいて、浅いコピーの配列を持っているように思えます。この問題に対する「通常の」解決策は、ユーザーがそれを行うのを難しくすることだと思います (つまり、Array<T>との間の変換を提供しないでくださいArray<U>)。しかし、あなたがあなたのアイデアに固執しているなら、これはうまくいくと思います:

template<typename Subclass>
class Array {
public:
    // ...
    Subclass *operator [] (size_t index) {
        assert( index < size_ );
        assert( dynamic_cast<Subclass*>(static_cast<Object*>(internal_[index])) != NULL );
        // ...
    }
    // ...
private:
    size_t size_;
    Subclass **internal_;
};

テンプレートのメタマジックと静的アサートを実行して、それSubclassが実際にのサブクラスであることを確認できますObject(正確には、まったく別のトピックです)。それが邪魔にならないようにしたら、 Object* にキャストしてからSubclass、 dynamic_cast に戻して目標を達成する必要があります。

于 2011-07-01T00:06:44.337 に答える
0

同じタイプのdynamic_castfrom と to は C++ ではノーオペレーションとして定義されているため、この例では「失敗」することはありません。typeid代わりに演算子を使用できます。

たとえば、次のプログラムはクラッシュする可能性が非常に高くなります (これは、ランダムなアドレスにあるオブジェクトから型情報を取得した場合の「予想される」結果です)。

int main()
{
    Object* garbage = reinterpret_cast<Object*>(0x12345678);
    if (typeid(*garbage) == typeid(Object))
        cout << "Your program thinks this garbage is an actual object!" << std::endl;
}
于 2011-06-30T23:40:56.130 に答える
0

仮想デストラクタを使用して共通の基本クラスを導入するだけです。空のベースの最適化では、これはおそらくオーバーヘッドを追加せず、うまく機能しますdynamic_cast

于 2011-06-30T23:54:10.623 に答える