Vektor-Funktion bricht nach einer Eingabe ab
-
@wob so ungefähr?
return this->users nullptr;
Zu Case 6: Ich iteriere durch mein Benutzer Vektor und mein Video-Vektor, wenn die ID des Videos gleich der ID des Favoritenvideos ist , dann gibt er
True
zurück, andernfalls wurde eines vom beiden nicht gefunden, daherfalse
.
Oder wo sitzt mein Denkfehler?
-
Einen
nullptr
kannst du nicht zurückgeben, da die Funktion ja einBenutzer
-Objekt zurückgeben soll (keinen Zeiger).
Du könntest aber am Ende wenigstens eine Exception werfen (wie inaddToFavorites
, welche du dann auch entsprechend umschreiben kannst, so daß sie diesefind
-Funktionen aufruft).Noch besser wäre es dann jedoch, die Funktion würde statt einer Kopie eine (konstante) Referenz zurückgeben, also
const Benutzer& OnlineVideothek::findUser(string name) // bzw. Benutzer& OnlineVideothek::findUser(string name)
Würdest du bisher nämlich Änderungen an dem zurückgegebenen Benutzer-Objekt machen (z.B. durch Aufruf von
setCurrent_video
), so wären diese Änderungen nicht imvector<Benutzer>
-Objekt desOnlineVideothek
-Objekts enthalten!Edit: In deinem
case 6
hast du denselben Logik-Fehler bzgl. demelse
wie in derlogin
-Funktion. Überlege mal, was bisher passiert, wenn der 2. Wert der gefundene sein soll?
-
Benutzer& OnlineVideothek::findUser(string name) { for (unsigned int i = 0; i < this->users.size(); i++) { if (this->users.at(i).get_User() == name) { return this->users.at(i); } else { throw runtime_error("User nicht gefunden"); } } // Hier müsste dann eine return funktion stehen }
Jetzt erscheint auch die Warnung, dass meine Funktion das Ende einer non-void Funktion erreicht.
Da wo mein Kommentar liegt, müsste ich da dementsprechend eine Exception schreiben?Bzgl.
case 6
: Die Funktion iteriert durch beide Vektoren, wenn erst der 2. Wert der gefundene sein soll, aber der erste Wert nicht der richtige ist, dann gibt er bereits beim 1. Wert ein false zurück und sucht gar nicht erst nach dem zweiten Wert, oder?
-
Jetzt überlege dir für diese Funktion mal, was passiert, wenn hier der 2. (oder 3. oder ...) Benutzer der zu findende ist?
Und dann sollte dir dein genereller Logik-Fehler klar sein.
-
@Th69 Theoretisch sucht die Funktion erst gar nicht nach dem 2 oder 3 Benutzer, wenn bereits beim ersten Benutzer ein
false
zurückgegeben wird, richtig?
-
Ja, genau!
-
Das heißt man bräuchte keine Ausgabe von false, sondern er soll solange suchen, bis er den richtigen User gefunden hat und dann dementsprechend ein
true
zurückgeben. Also brauche ich in dem Fall keinfalse
?
-
Ja, erst nach der Schleife gibst du
false
(oder eine Exception) zurück.
-
Super, habe ich geändert.
Aber bzgl. der Rückgabe sagtest du, dass ich eine Exception werfen soll oder am besten eine konstante Referenz.Da müsstest du mir mal auf die Sprünge helfen. Wie würde das aus der Sicht der Syntax aussehen?
-
Das mußt dir dir ja selber überlegen, was du als Rückgabe dann verwenden willst. Bei einem Objekt oder einer (konstanten) Referenz müßtest du ja einen Standard-Benutzer (o.ä.) zurückgeben - und dann entsprechend nach dem Aufruf abfragen.
Oder aber du nimmst einen Zeiger auf einen (konstanten) Benutzer und gibst dannnullptr
zurück und fragst dementsprechend ab (andererseits sind Zeiger immer etwas unschöner zu benutzen, wegen der Dereferenzierung mittels*
bzw.->
).
Wenn du aber eher davon ausgehst, daß es eine Ausnahme ist, daß ein Benutzer nicht gefunden wird, dann würde ich die Variante mit der Exception nehmen.
-
@Th69 sagte in Vektor-Funktion bricht nach einer Eingabe ab:
Das mußt dir dir ja selber überlegen, was du als Rückgabe dann verwenden willst. Bei einem Objekt oder einer (konstanten) Referenz müßtest du ja einen Standard-Benutzer (o.ä.) zurückgeben - und dann entsprechend nach dem Aufruf abfragen.
Oder aber du nimmst einen Zeiger auf einen (konstanten) Benutzer und gibst dannnullptr
zurück und fragst dementsprechend ab (andererseits sind Zeiger immer etwas unschöner zu benutzen, wegen der Dereferenzierung mittels*
bzw.->
).
Wenn du aber eher davon ausgehst, daß es eine Ausnahme ist, daß ein Benutzer nicht gefunden wird, dann würde ich die Variante mit der Exception nehmen.Hm, spannend. Ich habe eine andere Meinung. Für eine Funktion
get_user(const string &name)
- ok, die returnt einen User (Benutzer&
) - fein. Aber wenn ich eine Funktionfind_user
habe, dann sehe ich schon im Namen, das da etwas gesucht wird, das auch mal nicht gefunden werden kann. Da würde ich grundsätzlich erwarten, dass hier irgendwas rauskommt, das ich testen muss, ähnlich wie beistd::find
und Varianten. Ob es nun ein end-Iterator oder ein nullptr ist, egal.Daher würde ich
Benutzer* OnlineVideothek::findUser(const string &name) { for (unsigned int i = 0; i < this->users.size(); i++) { if (this->users.at(i).get_User() == name) return &this->users.at(i); } return nullptr; }
Wobei noch anzumerken wäre, dass ich die for-Schleife so nicht verwenden würde, aber das Beispiel jetzt nicht noch weiter ändern will. Die Frage ist auch, ob man nicht gleich eine
map<Username, User>
nehmen sollte. Im jetzigen Fall ist der Benutzer, der von dieser Funktion zurückkommt, nicht mehr gültig, wenn man eine andere Person einfügt.
Und @Suprax, du solltest dringend den Namen der Funktionget_User
überdenken! Der User ist doch schon das, was im Array users drin ist. Der sollte für den Namen eine Funktion wieget_name()
,get_username()
(oder ohne dasget_
) oder ähnlich haben! Außerdem ist es verwirrend, eine KlasseBenutzer
zu haben, diesen aber mitcreateUser
zu erstellen. Nimm einen Namen (den Englischen, wenn möglich).
-
Habs mittlerweile hinbekommen und die Fehler ausgebessert. Danke an alle!