2

基本的に私はclass Aとを持っていclass B : public Aます。

std::shared_ptr<std::vector<A*>そして、aをaにキャストしたいstd::shared_ptr<std::vector<B*>

問題は、std::vector<B>から継承されずstd::vector<A>smart_ptrどちらも継承されないことです。だから私は恐ろしいキャストをします:

  std::shared_ptr<VectorA> vector_a = * ((std::shared_ptr<VectorA>*)&vector_b);

コードはそこでコンパイルおよび実行されますが、安全ですか? http://liveworkspace.org/code/3dQTz1$0

4

4 に答える 4

3

これは恐ろしい解決策です。あるタイプのオブジェクトのベクトルを別のタイプにキャストすると、あらゆる種類の不正/未定義の動作が予想されます。

最初からvector of を使用し、そこstd::shared_ptr<A>にある型のオブジェクトへのポインタで初期化する必要Bがあります。

それが不可能な場合は、std::weak_ptr<A>これらのオブジェクトを 2 回管理することを避けるために、新しいベクトル保持を作成できます。

于 2013-02-05T21:51:35.543 に答える
3

そうしないでください。

B(pointers to) のベクトルは (pointers to)のベクトルではないA、またはより正確には、 (pointers to) のベクトルの普遍的に有効な置換ではないことを考慮してくださいA。したがって、このような変換を実行できないのには十分な理由があります。

のベクトルにあるのBは実際には一連のオブジェクトであり、(のインスタンスでもあります) であることは事実ですがA、次のアルゴリズムを検討してください。

void f(vector<A>& v)
{
    A a;
    v.push_back(a);
}

f()のベクトルで呼び出すと想像してくださいBBこれは、 type の要素のみを含むはずのコレクションにないクラスのインスタンスを追加しようとする試みBです。

ここでの解決策は、 のみを受け入れるコードをvector<A>vector<B>. つまり、テンプレートにする必要があります。たとえば、テンプレートは、 から派生した型のベクトルのみを引数として受け入れることができますA。これは、いくつかの SFINAE 手法と などの型特性を使用して非常に簡単に適用できstd::is_base_ofます。

于 2013-02-05T21:51:46.723 に答える
2

要素をキャストすることもできます:

A* a = vector_b->at (42);

あなたが望むものを与えます。

ここで、引数として受け取る関数を作成した場合shared_ptr<vector<A*>>、この状況から抜け出すための複数の解決策があります。

  • shared_ptr<A*[]>の代わりに使用shared_ptr<vector<A*>>します(お望みどおりに機能します)
  • A**引数として取る(および使用するvector_b->data ()) : 共有ポインターに結び付けられません。
  • より良い: [スマート] ポインターとして逆参照するイテレーターを使用します(チェーンAを思い出してください)。operator->
  • 使うstd::vector<std::shared_ptr<A>>(資源を浪費する)
于 2013-02-05T21:55:51.747 に答える
2

厳密に言えば、逆参照操作は成功するはずです。どちらのベクトルもポインタ コンテナであるため、プロダクション コードでは受け入れられませんが、相互にキャストしても同じ次元と配置が使用されます。

C++ はこれらの悪ふざけを避けるために豊富な抽象化を提供しますが、派生オブジェクトのベクトルを基本クラスへのポインターとして設定する方がよいでしょう。

于 2013-02-05T21:52:01.663 に答える