Nehmen Sie das folgende Beispiel:Können Sie gemeinsam genutzte Zeiger mit Nicht-Zeiger-Datenelementen mischen?
class BookManager
{
...
};
class Book
{
public:
void setBookManager(BookManager *bookManager) {m_bookManager = bookManager;}
private:
BookManager *m_bookManager;
};
Da der Anrufer der Regel nicht daran interessiert ist, einen Bookmanager für ein Buch zu halten, wenn das Buch gelöscht wird, und da mehr Bücher einen Bookmanager teilen können, mache ich den Zeiger auf Bookmanager, ein gemeinsamer Zeiger, wie folgt aus:
typedef std::shared_ptr<BookManager> BookManagerPtr;
class Book
{
public:
void setBookManager(BookManagerPtr bookManager) {m_bookManager = bookManager;}
private:
BookManagerPtr m_bookManager;
};
Problem ist, dass ein Modul in meiner Anwendung einen eigenen Book hat, dass es zu jedem seiner Bücher geben will, wie folgt aus:
class MyModule
{
public:
Book *createBook()
{
Book *newBook = new Book();
newBook->setBookManager(BookManagerPtr(&m_bookManager));
}
private:
BookManager m_bookManager;
};
Natürlich funktioniert das nicht, weil das letzte gelöschte Buch auch die BookManager-Instanz löscht, die es nicht löschen sollte, weil es ein normales Datenelement von MyModule ist.
Dies bedeutet, dass MyModule auch einen gemeinsamen Zeiger auf Bookmanager, wie diese verwendet werden soll:
class MyModule
{
public:
MyModule()
: m_bookManager(new BookManager())
{
}
Book *createBook()
{
Book *newBook = new Book();
newBook->setBookManager(m_bookManager);
}
private:
BookManagerPtr m_bookManager;
};
Ist dies der einzige Weg, um dieses Problem lösen? Oder gibt es eine Möglichkeit, noch normale Datenelemente zu haben und gemeinsame Zeiger zu verwenden (z. B. durch Initialisieren der Referenzzählung auf 1)?
Achten Sie darauf, keinen unbenannten gemeinsamen Zeiger wie in der ersten Version von MyModule :: createBook() zu verwenden. Siehe http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/shared_ptr.htm#BestPractices –