Pat*_*ick 2 c++ shared-ptr c++11
在一段新代码中,我有几个不同的类,它们互相引用.这样的事情(这不是我的实际情况,而是一个类似的例子):
class BookManager
{
...
};
class Book
{
public:
void setBookManager(BookManager *bookManager) {m_bookManager = bookManager;}
private:
BookManager *m_bookManager;
};
Run Code Online (Sandbox Code Playgroud)
每本书都指的是书籍管理员,但问题是许多书籍都有自己特定的BookManager,但有些书籍可能会共享一个共同的BookManager.
调用者并没有真正指定Book应该对其BookManager做什么,但在大约90%的情况下,BookManager可以与Book一起销毁.在大约10%的情况下,相同的BookManager可以重复用于多本书籍,并且不得使用书籍删除BookManager.
在这些90%的情况下,将BookManager与Book一起删除是很方便的,因为Book :: setBookManager的调用者不再需要记住BookManager.它只是因为书本身而死.
我看到两种解决方案可供选择.
首先是广泛使用共享指针.如果调用者之后在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;
};
Run Code Online (Sandbox Code Playgroud)
第二种解决方案似乎更容易,并允许我们使用正常的指针语法(BookManager *而不是std::shared_ptr<BookManager>),但它似乎比共享指针方法更"干净".
另一种选择可能是在BookManager中有一个typedef,如下所示:
class BookManager
{
public:
typedef std::shared_ptr<BookManager> Ptr;
...
};
Run Code Online (Sandbox Code Playgroud)
这允许我们写这个:
BookManager::Ptr bookManager;
Run Code Online (Sandbox Code Playgroud)
这看起来更像是普通的指针语法,而不是原始的共享指针语法.
有没有人有这两种方法的经验?还有其他建议吗?
在C++中,如果您对共同对象进行共享,非协调访问,那么最常见的方法是某种引用计数,您可以从中获得shared_ptr.
唯一的缺点是它在C++(特别是库)中并不普遍,所以有时你需要访问原始指针.在这些情况下,您需要小心保持对象存活.
我建议如果你使用shared_ptr - 尝试在任何地方使用它,除非它是不可能的.是的,如果你愿意,可以使用typedef.