10

C++0X/11 でスマート ポインターを使い始めたところ、奇妙な状況に遭遇しました。shared_ptr を使用してオブジェクトのインスタンスをアップキャストしたいと考えています。

クラス Extend はクラス Base から継承します。ここで、Base クラスには多態性を持たせるための仮想デストラクタがあります (それ以外の場合、dynamic_pointer_cast は非多態性クラスのキャストについて文句を言います)。

したがって:

std::shared_ptr<Base> obj = std::make_shared<Base>();

そして、私は:

obj = std::dynamic_pointer_cast<Extend>(obj);
  1. 安全ですか?
  2. オブジェクトへの他のポインターはどうなりますか? obj だけがそれを Extend として扱いますが、他の共有ポインタは引き続き Base として扱いますか?
  3. 同じインスタンスをアップキャストしても安全ですか、それとも何か他のことをする必要がありますか?

編集:答えてくれてありがとう。私がこの質問をした本当の理由は、SAX パーサーを使用して XML ドキュメントを処理することでしたが、アップ/ダウン キャストに夢中になりました。私が欲しかったのは:

std::shared_ptr<Extend> ex = std::dynamic_pointer_cast<Extend>(obj);
obj = ex;

しかし、それはまったく意味がありません。代わりに、オブジェクト ファクトリを使用します。

4

2 に答える 2

10

これはアップキャストではなく、ダウンキャストです (少ないクラスからより派生したクラスにキャストしています)。でも:

安全ですか?

はい、安全ですが、実行時の型が ではないオブジェクトへのポインターをダウンキャストしようとしているExtendため、null ポインターが返されます。

オブジェクトへの他のポインターはどうなりますか? obj だけがそれを Extend として扱いますが、他の共有ポインタは引き続き Base として扱いますか?

ここで誤解があります。オブジェクトへのポインターをダウンキャストしても、オブジェクトは変換されません。オブジェクトがターゲット タイプでない場合、そのオブジェクトへのダウンキャスト ポインターは取得されません。ポイントされたオブジェクト (任意のオブジェクト) の型は、コンパイル時に決定され、変更されません。

同じインスタンスをアップキャストしても安全ですか、それとも何か他のことをする必要がありますか?

ここで何を言っているのかわからないのですが、この質問の定式化はおそらく上記の誤解に由来しています。ただし、この命令:

obj = std::dynamic_pointer_cast<Extend>(obj);

objnull ポインターを作成します。派生クラスへの (スマート) ポインターを基底クラスへの (スマート) ポインターに割り当てることができるため、割り当て自体は有効です。ただし、割り当ての右側は (上記の理由により) ヌル ポインターに評価されるため、最終的には に割り当てられたヌル ポインターを取得しますobj

基本的に をリセットしているだけなので、 がによって作成されたオブジェクトへの最後の共有ポインタである場合obj、このオブジェクトは上記の代入が実行された後に破棄されます。objmake_shared<>()

于 2013-02-14T15:05:33.557 に答える