C++ 能否将共享指针与非指针数据成员混合使用?

C++ 能否将共享指针与非指针数据成员混合使用?,c++,c++11,shared-ptr,C++,C++11,Shared Ptr,以以下为例: class BookManager { ... }; class Book { public: void setBookManager(BookManager *bookManager) {m_bookManager = bookManager;} private: BookManager *m_bookManager; }; 由于调用者通常对删除某本书时保留该书的BookManager不感兴趣,而且多本书可以共

以以下为例:

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;
   };
class MyModule
   {
   public:
      Book *createBook()
         {
         Book *newBook = new Book();
         newBook->setBookManager(BookManagerPtr(&m_bookManager));
         }
   private:
      BookManager m_bookManager;
   };
class MyModule
   {
   public:
      MyModule()
      : m_bookManager(new BookManager())
         {
         }
      Book *createBook()
         {
         Book *newBook = new Book();
         newBook->setBookManager(m_bookManager);
         }
   private:
      BookManagerPtr m_bookManager;
   };
当然,这不起作用,因为上次删除的图书还将删除BookManager实例,它不应该删除该实例,因为它是MyModule的普通数据成员

这意味着MyModule还应该使用指向BookManager的共享指针,如下所示:

typedef std::shared_ptr<BookManager> BookManagerPtr;

class Book
   {
   public:
      void setBookManager(BookManagerPtr bookManager) {m_bookManager = bookManager;}
   private:
      BookManagerPtr m_bookManager;
   };
class MyModule
   {
   public:
      Book *createBook()
         {
         Book *newBook = new Book();
         newBook->setBookManager(BookManagerPtr(&m_bookManager));
         }
   private:
      BookManager m_bookManager;
   };
class MyModule
   {
   public:
      MyModule()
      : m_bookManager(new BookManager())
         {
         }
      Book *createBook()
         {
         Book *newBook = new Book();
         newBook->setBookManager(m_bookManager);
         }
   private:
      BookManagerPtr m_bookManager;
   };
这是解决这个问题的唯一办法吗?
或者有没有一种方法可以仍然拥有普通的数据成员并使用指向它的共享指针(例如,通过将其引用计数初始化为1)?

创建一个副本
bookManager(m_bookManager))
,使m_bookManager也成为bookManager,或者使book成为一个模板,从而允许它使用bookManager*和shared_ptr。
shared_ptr是关于共享所有权的,在您的示例中,MyModule拥有示例而book don不拥有,因此它与shared_ptr不兼容创建一个副本
BookManagerPtr(new BookMarkManager(m_bookManager))
,将m_bookManager也设为BookManagerPtr,或者将book设为模板,从而允许它使用bookManager*和shared_ptr。
shared_ptr是关于共享所有权的,在您的示例中,MyModule拥有该示例,而book don不拥有该示例,因此它与shared_ptr不兼容。

使用不起任何作用的自定义删除器怎么样?

使用不起任何作用的自定义删除器怎么样?

我知道您已经接受了一个答案,但是另一种方法(如果您有boost)可能是使用参考资料。默认情况下,
Book
类中不能有引用成员,但是如果将其包装为可选的,即
boost::optional
,则可以有一个引用,接下来,在
setBookManager
方法中,传入引用(或常量引用)并将其分配给可选的。要使用,就像使用智能指针一样使用deref…

我知道您已经接受了答案,但另一种方法(如果您有boost)可能是使用引用。默认情况下,
Book
类中不能有引用成员,但是如果将其包装为可选的,即
boost::optional
,则可以有一个引用,接下来,在
setBookManager
方法中,传入引用(或常量引用)并将其分配给可选的。使用,像智能指针一样删除…

建立非所有权模型的安全方法是使用
弱ptr
这样,生命周期仍然由
MyModule
控制,同时仍然有
Book
参考
BookManager
并知道它引用的
BookManager
是否仍然有效。

<模型非所有权使用
弱ptr
这种方式,生命周期仍然由
MyModule
控制,同时仍然拥有
Book
reference a
BookManager
并知道它引用的
BookManager
是否仍然有效。

注意不要像在第一个版本中那样使用未命名的共享指针MyModule::createBook()的。请参阅小心不要像在MyModule::createBook()的第一个版本中那样使用未命名的共享指针。看见