15

次のような 2 つの shared_ptr タイプがあるとします。

boost::shared_ptr<ObjA> sptrA;
boost::shared_ptr<ObjB> sptrB;

ここでsptrA->SomeMethod()、単純な ObjB 型 (共有 ptr ではない) を返したとします。その型を何らかの形で sptrB に格納することは可能ですか? 返された型インスタンスが自動的に boost_shared ptr に変換されるように、このようなことを行うことができます

sptrB = sptrA->SomeMethod(); 

私は好奇心からこの質問をしましたが、それが可能かどうか?

4

3 に答える 3

5

boost:shared_ptrオブジェクトを作成する最も標準的な方法はmake_shared、Boost が提供する関数を使用することです。

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

struct A {};

A generator() {
  return A();
}

int main()
{
  using namespace boost;
  shared_ptr<A> p = make_shared<A>(generator());
  return 0;
}

generator()関数は値によってオブジェクトを返すため、A上記の構文newは が のコピー コンストラクターで呼び出されA、結果のポインターが共有ポインター オブジェクトにラップされることを意味します。つまり、共有ポインタへの変換make_sharedを完全には実行しません。代わりに、ヒープ上にオブジェクトのコピーを作成し、そのためのメモリ管理を提供します。これは、必要なものである場合とそうでない場合があります。


これはC++11std::make_sharedの forと同等であることに注意してください。std::shared_ptr


質問で言及した便利な構文を提供する 1 つの方法は、変換演算子をshared_ptr<A>forに定義することAです。

struct A {
  operator boost::shared_ptr<A>() {
    return boost::make_shared<A>(*this);
  }
};

次に、次のように使用できます。

shared_ptr<A> p = generate();

これにより、関数によって返されたオブジェクトが自動的に「変換」されます。繰り返しますが、ここでの変換とは、実際にはヒープの割り当て、コピー、および共有ポインターへのラップを意味します。したがって、このような便利な変換演算子を定義することをお勧めするかどうかはよくわかりません。これにより、構文が非常に便利になりますが、すべての暗黙的な変換演算子と同様に、予期しない場所でこれらの「変換」が暗黙的に発生することも意味する場合があります。

于 2012-10-29T06:28:02.537 に答える
1

ObjA::SomeMethodこれは、コピー、参照、またはポインターの戻り値に正確に依存します。shared_ptr最初の 2 つのケースでは、 (ポインタshared_ptrが必要なため)にラップすることはできません。

3 番目のケースも考えられますが、慎重に進める必要があります。オブジェクトへのポインターを にラップしたら、shared_ptr他の誰もそのオブジェクトの有効期間を管理しようとしないことを確認してください。

たとえば、生のポインターを返し、それを共有ポインターにラップすると、プログラムの後半のある時点で誰かdeleteが同じポインターを使用すると、問題が発生します。

于 2012-10-29T04:32:19.937 に答える