你可以将共享指针与非指针数据成员混合使用吗?

时间:2010-12-07 10:25:42

标签: c++ c++11 shared-ptr

采用以下示例:

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)?

4 个答案:

答案 0 :(得分:2)

创建副本BookManagerPtr(new BookMarkManager(m_bookManager)),使m_bookManager成为BookManagerPtr或使书成为模板,从而允许它使用BookManager *和shared_ptr。 shared_ptr是关于共享所有权的,在你的例子中MyModule拥有示例而book不具备,因此它与shared_ptr不兼容

答案 1 :(得分:1)

如何使用无效的自定义删除工具?

答案 2 :(得分:1)

我知道你已经接受了答案,但另一种方法(如果你有提升)可能是使用引用。默认情况下,Book类中没有引用成员,但如果将其包装在可选的boost::optional<BookManager&>中,那么您可以在setBookManager方法中使用引用,传入引用(或const引用)并将其分配给可选项。要像使用智能指针那样使用deref;

答案 3 :(得分:0)

对非所有权进行建模的安全方法是使用weak_ptr这样,生命周期仍由MyModule控制,同时仍然Book引用BookManager并知道是否它引用的BookManager仍然有效。