2010-12-07 14 views
0

共有ポインターと非ポインターデータメンバーを混在させることはできますか?

class BookManager 
    { 
    ... 
    }; 

class Book 
    { 
    public: 
     void setBookManager(BookManager *bookManager) {m_bookManager = bookManager;} 
    private: 
     BookManager *m_bookManager; 
    }; 

呼び出し元は、ブックが削除された場合や、複数のブックがBookManagerを共有できるため、BookManagerの保守に通常は関心がないため、

問題は、自分のアプリケーション内のモジュールが独自のBookManagerを持っていて、次のようにそれぞれの書籍に与えたいということです。

class MyModule 
    { 
    public: 
     Book *createBook() 
     { 
     Book *newBook = new Book(); 
     newBook->setBookManager(BookManagerPtr(&m_bookManager)); 
     } 
    private: 
     BookManager m_bookManager; 
    }; 

もちろん、最後に削除された本はBookManagerインスタンスも削除するため、MyModuleの通常のデータメンバーであるため削除しないでください。

これは、MyModuleもBookManagerへの共有ポインターを次のように使用する必要があることを意味します。

class MyModule 
    { 
    public: 
     MyModule() 
     : m_bookManager(new BookManager()) 
     { 
     } 
     Book *createBook() 
     { 
     Book *newBook = new Book(); 
     newBook->setBookManager(m_bookManager); 
     } 
    private: 
     BookManagerPtr m_bookManager; 
    }; 

これを解決する唯一の方法はありますか? それとも、通常のデータメンバーを持ち、共有ポインタを使用する方法がありますか?(例えば、参照カウントを1に初期化する)

+0

MyModule :: createBook()の最初のバージョンと同じように、名前のない共有ポインタを使用しないように注意してください。 http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/shared_ptr.htm#BestPracticesを参照してください。 –

答えて

2

BookManagerPtr(new BookMarkManager(m_bookManager))コピーを作成するには、m_bookManagerをBookManagerPtrにするか、BookManager *とshared_ptrを使用できるようにbookをテンプレートにします。 shared_ptrはあなたの例では共有の所有権です。MyModuleはその例を所有しており、ブックは共有していませんので、shared_ptrと互換性がありません。

1

何もしないカスタムのdeleterを使用するのはどうですか?

1

私はあなたが答えを受け入れたことを知っていますが、別のアプローチ(あなたがブーストしている場合)は参照を使用することができます。デフォルトでは、Bookクラスのリファレンスメンバーを持つことはできませんが、オプションのboost::optional<BookManager&>にラップすると、setBookManagerメソッドで参照を持つことができ、リファレンス(またはconst参照)を渡して、これはオプションです。あなたはスマートポインタ...

0

安全な方法は、非所有権はweak_ptrでまだBook参照BookManagerを持つと知っながら寿命はまだMyModuleによって制御されているこの方法ですモデル化するだろうとDEREF、使用するにはBookManager場合参照はまだ有効です。

関連する問題