新しいコードでは、お互いを参照するいくつかの異なるクラスがあります。このような何か(これは私の実際の状況が、似たような例ではありません):C++でのメモリ所有権を管理する最も良い方法は?共有ポインタまたは他のメカニズム?
class BookManager
{
...
};
class Book
{
public:
void setBookManager(BookManager *bookManager) {m_bookManager = bookManager;}
private:
BookManager *m_bookManager;
};
すべての本がブックマネージャを意味するが、問題は、多くの書籍は、独自の特定のBookManagerを持っているということですが、いくつかの本共通のBookManagerを共有することができます。
呼び出し元はBookManagerで何をすべきかを実際に指定していませんが、約90%の場合BookManagerはBookと一緒に破棄できます。このケースの約10%で、同じBookManagerが複数の書籍に再利用され、BookManagerをBookで削除してはなりません。
Book :: setBookManagerの呼び出し元がBookManagerをもう覚えておく必要がないため、BookManagerをブックとともに削除すると、その90%のケースで便利です。それはただ本自体と一緒に死にます。
私はこれを解決するための2つの解決策を見ています。
まず、共有ポインタを広範囲に使用することです。その後、呼び出し元がBookManagerにそれ以上興味をもたない場合は、共有ポインタは保持されません。それでも興味がある場合や、BookManagerを複数の書籍で共有したい場合は、共有ポインタを保持して複数の書籍に渡します。
class Book
{
public:
void setBookManager(BookManager *bookManager, book takeOwnership=true)
{
m_bookManager = bookManager;
m_hasOwnership = takeOwnership;
}
~Book()
{
if (m_hasOwnership && m_bookManager) delete m_bookManager;
}
private:
BookManager *m_bookManager;
bool m_hasOwnership;
};
第二の溶液は、はるかに簡単ようで、私たちは通常のポインタの構文を使用することができます(BookManager *
として:
第二の代替は、このように、本の所有権をどうするか、明示的にブックを伝えることですstd::shared_ptr<BookManager>
と反対)が、共有ポインタアプローチよりも「クリーン」ではないようです。
class BookManager
{
public:
typedef std::shared_ptr<BookManager> Ptr;
...
};
私たちはこれを書くことができます::
別の方法としては、このようなBookManagerの中のtypedefを持っているかもしれません
以上、通常のポインタの構文のように見えるBookManager::Ptr bookManager;
元の共有ポインタ構文。
どちらのアプローチでも経験がありますか? 他の提案はありますか?
「不可能でない限りどこでも使用してみてください」 - これが、循環参照を追跡するのが難しくなる方法です。 –