All diese Smart/Unique und was weiß ich Pointer Sachen haben sich mir nie erschlossen.
Alles unnötige Hilfskonstrukte meiner Meinung nach.
Also die erste Frage ist halt, wer ist für den Lebenszyklus (Owner/Ownership) eines Book zuständig. Das erkennt man leider
in deinem Beispiel nicht. Wer erstellt eine Instanz von Book? Der sollte dann auch für das Löschen zuständig sein.
Wie BlueCobold richtig sagt ist die Verwendung eines RawPointers vollkommen korrekt dann.
Die Frage ist halt wie immer bei einer "get" Methode, wie man deutlich macht, dass eventuell kein Book da ist.
Hier gibt es mehrere Möglichkeiten
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
|
map<uint32_t,Book> m_Books;
Book* getBook(uint32_t id) {
if ( ... found ... ) {
return &m_Books[id];
}
return 0;
}
|
Dann kann der Aufrufer auf "0" testen und weiß wann kein Buch da ist.
Ein anderer Ansatz ist, dass Du einen Pointer reinreichst und dann noch einen bool als Rückgabewert hast:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
|
bool getBook(uint32_t id,Book* book) {
if ( .. found... ) {
book->id = m_Books[id].id;
return true;
}
return false;
}
|
Den Ansazt verwendet Microsoft z.B. in DirectX wo allerdings ja immer HRESULT der Rückgabewert ist.
Der dritte Ansatz wäre mit Referenzen zu arbeiten und dann mittels assert sicherzustellen, dass ein Book existiert:
|
C-/C++-Quelltext
|
1
2
3
4
|
const Book& getBook(uint32_t id) {
assert(... book exists .... );
return m_Books[id];
}
|
Der Vorteil ist, dass Du nicht mit Pointer arbeitest und niemand Dir Dein Book löschen kann. Der Nachteil ist, dass Du
nur einen Check zur Laufzeit hast und das assert dein Programm beendet. Alternative wäre sicherlich noch eine
|
C-/C++-Quelltext
|
1
2
3
4
5
6
|
bool contains(uint32_t id) {
if ( ... book exists ... ) {
return true;
}
return false;
}
|
Methode. Dann kannst Du das vorher abfragen und bleibst bei den Referenzen. Übrigens ist es immer sinnvoll beide
Arten dann zu implementieren, sprich eine const und eine ohne const
|
C-/C++-Quelltext
|
1
2
|
const Book& get(uint32_t id) const {}
Book& get(uint32_t id) {}
|
Wie Du es machst es auch persönlicher Geschmack. Hauptsachen man macht es dann konsistent innerhalb eines Projektes.
Außerdem siehst Du an den Beispielen, dass diese Smart Pointer gar nicht nötig sein und durch ein bisschen überlegen über Onwership etc. auch
völlig unnötig.