2010-12-07 47 views
0

看看下面的例子:您可以將共享指針與非指針數據成員混合嗎?

class BookManager 
    { 
    ... 
    }; 

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

由於主叫方通常是不感興趣,保持BookManager的一本書如果這本書被刪除,因爲多本圖書可以共享一個BookManager的,我做的指針BookManager的,一個共享指針,就像這樣:

typedef std::shared_ptr<BookManager> BookManagerPtr; 

class Book 
    { 
    public: 
     void setBookManager(BookManagerPtr bookManager) {m_bookManager = bookManager;} 
    private: 
     BookManagerPtr m_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 – 2010-12-07 13:23:32

回答

2

創建副本BookManagerPtr(new BookMarkManager(m_bookManager)),使m_bookManager成爲BookManagerPtr,或者使書成爲模板,從而允許其使用BookManager *和shared_ptr。 shared_ptr是關於共享所有權,在你的例子中MyModule擁有的例子和書沒有,所以它不兼容shared_ptr

1

如何使用自定義刪除器什麼都不做?

1

我知道你已經接受了答案,但另一種方法(如果你有提升)可以使用引用。默認情況下,您不能在Book類中擁有引用成員,但是如果您將其封裝在可選的中,則可以在setBookManager方法中具有引用,接下來,傳入引用(或const引用)並分配這到可選。要使用,DEREF,你會智能指針...

0

的安全的方式來建模非所有權與weak_ptr這樣的壽命仍然MyModule控制的同時還具有Book參考BookManager,知道如果BookManager它的引用依然有效。