Rückgabe von "Objekten" der Basisklasse
-
Hallo,
ich habe folgende Klassenhierarchie:Basisklasse A, davon abgeleitet B, C, D ...
Ich habe eine Fabrikklasse die Objekte der Klassen B, C, D erzeugen und "als A zurückgeben" soll + ein bool, das anzeigt, ob die Produktion erfolgreich war. Momentan benutze ich (vereinfacht) folgendes Schema:
class Factory { bool tryProduce(A *&zurueck) { zurueck = new B(); return true; } }Benutzt wird sie so:
int main(void) { Factory f(); A* bla = 0; while(...) { bool b = f.tryProduce(bla); if (b) { std::cout << bla->toString(); } else { ... } } }Gibt es eine bessere Möglichkeit als mit Referenzen auf Pointer zu arbeiten? Damit kommt ja leider dynamische Speicherallokation ins Spiel.
Ich komme von JAVA und dort lässt sich das alles viel einfacher lösen dank JAVA-Referenzen

-
struct Factory { A* tryProduce() { return new B(); } } int main() { Factory f; //mit Klammern ist das eine Funktionsdeklaration while(...) { A* obj = f.tryProduce(); if (obj) { std::cout << obj->toString(); } else { ... } } }Wenn das Erzeugen fehlschlägt, gibst du 0/nullptr zurück oder wirfst eine Exception.
Ich komme von JAVA und dort lässt sich das alles viel einfacher lösen dank JAVA-Referenzen

Java-Referenzen sind nichts anderes als Zeiger.
Mit rohen Zeigern zu arbeiten empfiehlt sich in C++ meist nicht, stattdessen solltest du intelligente Zeiger einsetzen (im wesentlichen unique_ptr und shared_ptr).
-
Okay, nur muss ich mir eben in JAVA erstmal keine großen Gedanken um den Speicher machen.
Über shared_ptr hab ich schon nachgedacht. Ich dachte halt, es gibt eine andere Standardmethode mein Problem zu lösen, ohne Zeiger.
-
Du willst keinen shared_ptr sondern unique_ptr. Ich weiß gar nicht, warum hier dauernd irgendwelche Leute shared_ptr empfehlen. Haltet doch einfach mal die Fresse, wenn ihr keine Ahnung habt. Danke.
-
314159265358979 schrieb:
Haltet doch einfach mal die Fresse, wenn ihr keine Ahnung habt.
Besoffen?

-
nope, du?
-
314159265358979 schrieb:
nope, du?
Noch nicht...
Aber danke für die Klarstellung.
-
314159265358979 schrieb:
Du willst keinen shared_ptr sondern unique_ptr. Ich weiß gar nicht, warum hier dauernd irgendwelche Leute shared_ptr empfehlen. Haltet doch einfach mal die Fresse, wenn ihr keine Ahnung habt. Danke.
Fakt ist, solange du nicht weißt was mit den Objekten gemacht wird, kannst du nicht vorwerfen das falsche Smartpointer empfohlen werden.
Grundsätzlich ist shared_ptr ein "teurer" Smartpointer, dennoch kann er je nach Aufgabenstellung der einzig richtige sein (Auch wenn der Standard wohl eher etwas wie der unique_ptr sein sollte).
Ich sehe übrigens in keinen Post eine Empfehlung zwangsweise den shared_ptr zu verwenden, es wurde unique_ptr und shared_ptr zusammen erwähnt.
-
totalerbeginner:
ne, gibt keine Standardmethode. Du brauchst Referenzen/Zeiger in jedem Fall, da Du bei Rückgabe per value einigen Kopieraufwand hättest (der wegoptimiert werden könnte, worauf ich mich aber nicht so gerne verlasse) und v.a. bewirkt, dass die Infos von B,C,D bei der Verkürzung auf A gelöscht werden (Slicing).Schließe einfach einen besagten Smartpointer um das Objekt herum. Das ist meiner Ansicht nach eine gute Methode Factory-Rückgabewerte umzusetzen. Bzw. ich mache das bei mir so, dass ich mir zwar pure Zeiger zurückliefern lasse, diese aber in einem unique_ptr verstaue.
-
Danke.
Ich muss mal schauen, welchen smarten Pointer ich am Schluss benötige.
Btw. kann da nix schiefgehen, wenn du den "pure" Zeiger erst nachträglich verstaust? Wenn in der Zwischenzeit (mittels pure Pointer) schon ein anderer Pointer auf das Objekt erzeugt worden wäre oder so? Nur aus Interesse.
-
Wenn man pure Zeiger zurückgibt, muss der Aufrufer natürlich die Disziplin besitzen, jeweils sofort einen
unique_ptreinzusetzen. Allerdings sehe ich den Sinn nicht ganz, wenn das der ganze Einsatzzweck sein soll, zumalunique_ptrmovable ist und somit von Funktionen zurückgegeben werden kann.