2

「this」ポインターをスマートポインターと組み合わせて使用​​しないようにするにはどうすればよいですか?これを回避するためのデザインパターン/一般的な提案はありますか?

次のいずれかなので、2つを組み合わせるのはノーノーだと思います。

  1. そもそもスマートポインターを使用するという点を打ち負かす、スマートポインター管理オブジェクトへのネイティブポインターを渡しているのです。
  2. 「this」ポインターを使用時にスマートポインターでラップすると、たとえば「return CSmartPtr(this);」のように、同じオブジェクトを管理する複数のスマートポインターが効果的に設定されるため、最初のポインターの参照カウントはゼロになります。他の下からオブジェクトを破壊する、または
  3. これらの場合に返すCSmartPtr(this)の値を保持するメンバー変数がある場合、最終的には循環参照になり、参照カウントは常に1になります。

少しコンテキストを与えるために、私は最近、STLコンテナーをオブジェクトと組み合わせる場合の悪影響(浅いコピーの繰り返し、基本クラスのコンテナーを使用する場合のスライスなど)について学びました。そのため、コードでのこれらの使用法の一部を次のように置き換えます。オブジェクトへのスマートポインタ。いくつかのオブジェクトは、「this」ポインタを使用して自分自身への参照を渡します。これは私が立ち往生している場所です。

スマートポインタ+「これ」は有害だと考えられていますか?やや似たような問題について尋ねましたが、私はBoostを使用していないので、答えは役に立ちません。

編集:私がやっていたことの(非常に工夫された)例は次のようになります

...::AddToProcessingList(vector<CSmartPtr> &vecPtrs)
{
    vecPtrs.push_back(CSmartPtr(this));
}
4

3 に答える 3

2

ほとんどのスマート ポインター フレームワークは、これを回避する手段を提供します。たとえば、Boost.SmartPtr はenable_shared_from_this<T>基本クラスとして使用する CRTP クラスを提供し、共有ポインターが同じオブジェクトへの 2 つのポインターにならないようにすることができます。

于 2009-09-02T00:10:53.137 に答える
2

2 つを組み合わせることができますが、所有権の問題については常に頭に入れておく必要があります。一般に、私が従う規則は、その時点でオブジェクトの所有権を取得していることが確実でない限り、生のポインターを (所有権のある) スマート ポインターに決して変換しないことです。これを行うのが安全な時間は明らかですが、次のようなことを含めてください。

  1. オブジェクトを ( 経由でnew)作成しました
  2. セマンティックが明らかに所有権の1つである外部メソッド呼び出しからオブジェクトが渡されました(addコンテナクラスへのなど)
  3. オブジェクトは別のスレッドに渡されています

ルールに従っていて、あいまいな所有権の状況がない限り、問題が発生することはありません。

上記の例では、次のように見ることができます。

  1. そもそもスマートポインターを使用するポイントを無効にするスマートポインター管理オブジェクトへのネイティブポインターを渡しています

この場合、ネイティブ ポインターを渡しているため、私のルールでは所有権を譲渡していないと見なすことができ、スマート ポインターに変換することはできません。

  1. 使用時に「this」ポインターをスマート ポインターでラップする場合 (たとえば、「return CSmartPtr(this);」)、同じオブジェクトを管理する複数のスマート ポインターを効果的に設定したことになるため、参照カウントがゼロの最初のポインターが他のオブジェクトの下からオブジェクトを破壊する

オブジェクトが他のスマート ポインターによって既に所有されていると述べたので、これは明らかに違法です。

  1. これらの場合に返される CSmartPtr(this) の値を保持するメンバー変数がある場合、最終的には参照カウントが常に 1 になる循環参照になります。

一部の外部コードがメンバー変数を暗黙的に所有している場合、これは実際に管理できます。このコードはclose()、オブジェクトが解放される前のある時点で何らかのメソッドを呼び出すことができます。明らかに、その外部コードはオブジェクトを所有しているため、実際にはスマートポインター自体が必要です。

ブースト ライブラリ (使用していないとおっしゃいましたが) を使用すると、さまざまな種類の所有権 (スコープ、共有、弱いなど) に沿ってスマート ポインター ライブラリが分割されるため、このような問題の管理が容易になります。

于 2009-09-02T00:12:41.327 に答える
1

この問題に対するかなり強力な解決策の 1 つは、侵入型のスマート ポインターを使用することです。をインスタンス化するRefCountedPtr<T>には、T を RefCount から派生させる必要があります。寿命を決定する単一のカウンターを保持するため、これによりRefCountedPtr<T>fromの構築が可能になります。thisthis->RefCount::m_count

欠点: オブジェクトをスタックに置くと、未使用の RefCount があります。

于 2009-09-02T07:51:52.237 に答える