7

まず第一に、これはshared_ptrの目的と完全に矛盾していることに気づきました。私は、ParticleSystemのインスタンスが、各パーティクルに使用されるテクスチャを設定するために、構築中にshared_ptrが渡されることを期待するライブラリコードを扱っています。重要なのは、テクスチャが具体的な所有権を持つ方法でプログラムの残りの部分をすでに構築していることです(それが正しい用語である場合)-TextureCacheはすべてのテクスチャを所有しています。したがって、テクスチャを削除せずにこのParticleSystemクラスを操作する方法が必要です。そのような新しいインスタンスを単純に作成するParticleSystem(std::shared_ptr<Texture>&myTexture)と、破壊時にテクスチャを破壊しようとします(これは、テクスチャがで作成されていないため、不要で無効な操作ですnew)。

この問題の周りで私が見る最もきれいな方法は次のようなものです:

  1. ParticleSystemを作成する関数でテクスチャを保持するshared_ptrを作成します。
  2. 次に、placement newを使用して、先ほど作成したshared_ptrと同じメモリ位置にshared_ptrを再構築します。テクスチャの参照カウントは2になります。
  3. パーティクルシステムを作成します。
  4. shared_ptrをスコープ外にします。そのデコンストラクタは、スタックに割り当てられたために呼び出され、参照カウントを1だけデクリメントします。したがって、オブジェクトの参照カウントは常に実際よりも1大きくなるため、自動的に破棄されることはありません。

この解決策は健全だと思いますが、それでも信じられないほどハックな感じがします。私の問題を解決するためのより良い方法はありますか?

4

4 に答える 4

5

アンマネージポインター(自分で管理する)を、などのスマートポインターを期待するコードに渡したい場合は、エイリアシングコンストラクターをshared_ptr使用して空のnullではないポインターを作成することで、«スマート»ポインター機能を無効にできます。shared_ptr

Texture* unmanagedPointer = ...
shared_ptr<Texture> smartPointer(shared_ptr<Texture>(), unmanagedPointer);

このソリューションは、制御ブロックの割り当てと参照カウントが行われていないため、他の人が提案したカスタム削除ツールよりも効率的で短いです。

いくつかの追加の詳細はここで見つけることができます:

C++の空のstd::shared_ptrとnullのstd::shared_ptrの違いは何ですか?

std::make_sharedで大きなメモリ割り当てを回避する方法

于 2015-04-17T21:43:59.123 に答える
3

何もしないカスタム削除機能をshared_ptr使用して作成できます。これにより、これが所有するテクスチャが削除されなくなります。shared_ptr

struct null_deleter
{
    void operator()(void const *) const
    {
    }
};

shared_ptr<Texture> CreateTexture(Texture* myTexture)
{
    shared_ptr<Texture> pTexture(myTexture, null_deleter());
    return pTexture;
}
于 2012-08-26T07:26:32.913 に答える
1

shared_ptrカスタム削除機能を提供できます。したがってshared_ptr、mallocで割り当てられたメモリ、または使用しているメモリ割り当てスキームに使用できます。これを使用して、ミューテックスのロックを自動的に解除したり、ファイルを閉じたりすることもできますが、私は逸脱します。shared_ptr参照カウントが0に達したときに何も実行しないnull削除機能を使用してを作成できます。

于 2012-08-26T07:27:41.427 に答える
0

Vaughn shared_ptrCatoが提案するように、キャッシュに保存します。誰も使用していないときにキャッシュからテクスチャを削除するには、 returnsuse_countの関数が返されるかどうかを確認するだけです。つまり、キャッシュが唯一の所有者です。shared_ptr1

于 2012-08-26T05:27:51.343 に答える