0

私は、メモリ管理のための最新のC ++の取り組みで、スマートポインタの使用をいじっています。これの一部は、一連のマップを使用して、文字列をクラス(IBlockInputと呼ばれる)に結び付け、クラスを「コンテキスト」内の現在の値に結び付けることです。2つのオプションがありますが、どちらにも同じ問題があります。

オプション1:クラスの現在の値がクラス内に保存され、コンテキストで並べ替えられます

オプション2:クラスの現在の値がコンテキスト内に保存され、クラスで並べ替えられます

ここでの問題は、どちらかのオブジェクトがもう一方のオブジェクトより先に死ぬ可能性があることです。すべての入力が残っている間にコンテキストが破棄されるか、コンテキストが残っている間に入力が破棄される可能性があります。人が死んだとき、そのための資源を解放する必要があります。私がこれまでに持っているのは(オプション2を使用して):

std::map<std::string, boost::weak_ptr<IBlockInput> > inputs;
std::map<boost::weak_ptr<IBlockInput>, boost::shared_ptr<std::vector<double> > > inputValues;

これらをこのように分離する必要がある理由は、他のクラス(IOutputBlocks)が、ポインターに基づいてIInputBlocksの値にアクセスして設定する必要があるためです。

これについて私が持っているいくつかの質問があります:

質問1:法線マップのようにinputValuesマップにアクセスし、ポインター(boost :: shared_ptr / boost :: weak_ptr ... T *ではない)を渡してアクセスできますか?それが実際の方法である場合は、weak_ptrsまたはshared_ptrsも使用できます

質問2:必要に応じてオブジェクトを停止させるために弱ポインタ​​ーを使用しています(上記のオプション1を実行している場合、コンテキストを指す弱ポインタ​​ーを使用する必要があります)。ウィークポインターが期限切れになり、マップでそれにアクセスしようとするとどうなりますか?それが指し示すデータは古くから失われていますか、それとも生のポインターで機能しますか?

質問3:おそらくこれを行うためのより良い方法は、生のポインターをキー/値として使用し、次に次のような弱いポインター(ある種のライブチェック用)を含む補足マップを作成することです。

std::map<std::string, IBlockInput*> inputs;
std::map<IBlockInput*, boost::shared_ptr<std::vector<double> > inputValues;
std::map<IBlockInput*, boost::weak_ptr<IBlockInput> > pointerCache;

次に、を使用して「ライブチェック」を実行し、pointerCachedoubleのベクトルを存続させ、その方法でメモリを管理する必要があるかどうかを確認できます。:入力ベクトルは比較的頻繁に更新されます。

このための推奨される方法は何ですか?私は一般的にスマートポインターをブーストして使用するのは非常に新しいです(私は過去数か月間C#で甘やかされており、この種のことを心配する必要はありませんでした)。

4

1 に答える 1

0

std::map<boost::weak_ptr<IBlockInput>, boost::shared_ptr<std::vector<double> > > inputValues; - これは悪いです。weak_ptr死ぬと、と比較され、nullptrその順序は維持されません。未定義の動作が発生します(実際には、無限ループとクラッシュが発生します)

sのキーに使用するものに注意してくださいstd::map

割り当てが解除される可能性のある生のポインタを使用することは、有効なポインタが無効になるABA問題のために適切ではなく、新しいポインタがそれに等しく割り当てられます。make_shared(この種のものを実際に機能させるためにの実装の詳細を悪用していますが、それは厄介で危険です)

おそらく、ある種の二重間接参照が必要です。ここでは、ポインターからポインターに相当するものがあります。それらをハンドルと呼びます。ハンドルの有効期限の内側のポインターにより、ハンドルはマップ内で登録解除され、すべてのマップから外れると、それ自体が破棄されます。うまくいくかどうかはわかりませんが、うまくいくかもしれません。最初にいじる必要があるのではないかと思います。

ハンドルは(外側の)ポインタ値で順序付けられるため、順序付けは維持されます。ハンドルが有効かどうかを判断するには、外部ポインターと内部ポインターの両方の有効性を確認する必要があります(したがって、null以外のハンドルは「逆参照」に対して無効になる可能性があります)。

しかし、私はこれをきれいにする方法を考えることができません。

于 2012-12-10T04:36:24.550 に答える