可以将共享指针与非指针数据成员混合使用吗?
采取以下示例:
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)?
Take the following example:
class BookManager
{
...
};
class Book
{
public:
void setBookManager(BookManager *bookManager) {m_bookManager = bookManager;}
private:
BookManager *m_bookManager;
};
Since the caller is typically not interested in keeping a BookManager for a Book if the Book is deleted, and since multiple Books can share a BookManager, I make the pointer to BookManager, a shared pointer, like this:
typedef std::shared_ptr<BookManager> BookManagerPtr;
class Book
{
public:
void setBookManager(BookManagerPtr bookManager) {m_bookManager = bookManager;}
private:
BookManagerPtr m_bookManager;
};
Problem is that a module in my application has its own BookManager that it wants to give to each of its books, like this:
class MyModule
{
public:
Book *createBook()
{
Book *newBook = new Book();
newBook->setBookManager(BookManagerPtr(&m_bookManager));
}
private:
BookManager m_bookManager;
};
Of course this doesn't work because the last deleted book will also delete the BookManager instance, which it shouldn't delete because it's a normal data member of MyModule.
This means that MyModule should also use a shared pointer to BookManager, like this:
class MyModule
{
public:
MyModule()
: m_bookManager(new BookManager())
{
}
Book *createBook()
{
Book *newBook = new Book();
newBook->setBookManager(m_bookManager);
}
private:
BookManagerPtr m_bookManager;
};
Is this the only way to solve this?
Or is there a way to still have normal data members and use shared pointers to it (e.g. by initializing its reference count to 1)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
创建一个副本 BookManagerPtr(new BookMarkManager(m_bookManager)) ,使 m_bookManager 也成为 BookManagerPtr 或使 book 成为模板,从而允许它使用 BookManager* 和 shared_ptr。
shared_ptr 是关于共享所有权的,在您的示例中,MyModule 拥有该示例,而本书则没有,因此它与 shared_ptr 不兼容
create a copy
BookManagerPtr(new BookMarkManager(m_bookManager))
, make m_bookManager a BookManagerPtr too or make book a template thus allowing it to use BookManager* and shared_ptr.shared_ptr is about shared ownership, in your example MyModule owns the example and book don't, so it's not compatible with shared_ptr
使用不执行任何操作的自定义删除器怎么样?
What about using custom deleter which does nothing?
我知道您已经接受了答案,但另一种方法(如果您有提升)可能是使用参考文献。默认情况下,您不能在
Book
类中拥有引用成员,但是如果您将其包装在可选的即boost::optional
中,那么您可以有了一个引用,接下来,在setBookManager
方法中,传入该引用(或 const 引用)并将其分配给可选值。要使用,请像使用智能指针一样取消引用......I know you've accepted an answer, but another approach (if you have boost) could be to use references. By default you can't have a reference member in the
Book
class, however if you wrap it in an optional i.e.boost::optional<BookManager&>
then you can have a reference, next, in thesetBookManager
method, pass in the reference (or const reference) and assign this to the optional. To use, deref as you would a smart pointer...对非所有权进行建模的安全方法是使用
weak_ptr
,这样生命周期仍然由MyModule
控制,同时仍然让Book
引用>BookManager
并了解它引用的BookManager
是否仍然有效。The safe way to model non-ownership is with a
weak_ptr
this way the lifetime is still controlled byMyModule
while still havingBook
reference aBookManager
and know if theBookManager
it references is still valid.