C ++ - Methode, die eine Struktur zurückgeben kann / kann

8

Ich habe eine C ++ - Struktur und eine Methode:

%Vor%

Ich kann eine Account-Struktur zurückgeben, wenn das Konto existiert, aber was tun, wenn es kein Konto gibt?

Ich dachte daran:

  • Ein "is valid" -Flag auf der Struktur (also kann eine leere zurückgegeben werden, wobei diese auf false gesetzt ist)
  • Ein zusätzlicher "is valid" -Zeiger (const string & amp; id, int * is_ok), der gesetzt wird, wenn die Ausgabe gültig ist
  • Einen Account * zurückgeben und entweder einen Zeiger auf eine Struktur oder NULL zurückgeben, wenn er nicht existiert?

Gibt es einen besten Weg, dies zu tun?

    
Lucky5 13.12.2010, 15:38
quelle

11 Antworten

13

Sie haben die offensichtlichste Version in C ++ vergessen:

%Vor%

Gebe true zurück und fülle die angegebene Referenz aus, wenn das Konto existiert, sonst gib false zurück.

Es kann auch nützlich sein, die Tatsache zu verwenden, dass Zeiger null sein können und Folgendes haben:

%Vor%

Dies könnte so definiert werden, dass true zurückgegeben wird, wenn die Konto-ID existiert, aber nur (natürlich) um das angegebene Konto auszufüllen, wenn der Zeiger nicht null ist. Manchmal ist es praktisch, in der Lage zu sein, die Existenz zu testen, und das spart die Notwendigkeit einer dedizierten Methode nur für diesen Zweck.

Es ist eine Frage des Geschmacks, was Sie bevorzugen.

    
unwind 13.12.2010, 15:40
quelle
7

Von den gegebenen Optionen würde ich Account* zurückgeben. Der zurückkehrende Zeiger kann jedoch einige negative Auswirkungen auf die Schnittstelle haben.

Eine andere Möglichkeit ist throw eine Ausnahme, wenn es kein solches Konto gibt. Sie können auch boost::optional ausprobieren.

    
Juraj Blaho 13.12.2010 15:43
quelle
6

Sie können auch das Null-Objektmuster ausprobieren.

    
Goz 13.12.2010 15:41
quelle
3

Es hängt davon ab, wie hoch die Wahrscheinlichkeit ist, dass das Konto nicht existiert.

Wenn es wirklich außergewöhnlich ist - tief in den Tiefen des Inneren des Bankensystems, wo die Daten gültig sein sollen - dann vielleicht eine Ausnahme werfen.

Wenn es sich um eine Benutzerschnittstellenebene handelt, die Daten validiert, dann werfen Sie wahrscheinlich keine Ausnahme.

Das Zurückgeben eines Zeigers bedeutet, dass jemand den zugewiesenen Speicher freigeben muss - das ist unordentlicher.

Können Sie eine 'Marker-ID' (z. B. 0) verwenden, um 'ungültiges Konto' anzugeben?

    
Jonathan Leffler 13.12.2010 15:42
quelle
2

Ich würde Account* verwenden und der Methode einen Dokumentationskommentar hinzufügen, der besagt, dass der Rückgabewert NULL sein kann.

    
rotti2 13.12.2010 15:44
quelle
2

Es gibt mehrere Methoden.

1) Wirf eine Ausnahme aus. Dies ist nützlich, wenn GetAccountById das Konto nach Wert zurückgeben soll und die Verwendung von Ausnahmen Ihrem Programmiermodell entspricht. Einige werden Ihnen sagen, dass Ausnahmen nur in Ausnahmefällen "gemeint" sind. Dinge wie "out of memory" oder "Computer in Brand". Dies ist sehr umstritten, und für jeden Programmierer, den Sie finden, der sagt, Ausnahmen sind nicht für die Flusskontrolle, finden Sie einen anderen (mich eingeschlossen), der sagt, dass Ausnahmen für die Flusskontrolle verwendet werden können. Sie müssen darüber nachdenken und selbst entscheiden.

%Vor%

2) Rückgabe nicht und Account nach Wert. Übergeben Sie stattdessen mit Zeiger (vorzugsweise intelligenter Zeiger) und geben Sie NULL zurück, wenn Sie das Konto nicht gefunden haben:

%Vor%

3) Zurückgeben eines Objekts, das ein 'Präsenz'-Flag hat, das angibt, ob das Datenelement vorhanden ist oder nicht. Boost.Optional ist ein Beispiel für ein solches Gerät, aber Falls Sie Boost hier nicht verwenden können, ist ein Vorlagenobjekt mit einem bool -Member, das true ist, wenn das Datenelement vorhanden ist, und false , wenn dies nicht der Fall ist. Das Datenelement selbst wird im value_ -Member gespeichert. Es muss standardmäßig konstruierbar sein.

%Vor%

Der Einfachheit halber würde ich einen Typedef für Account erstellen:

%Vor%

... und dann von der Funktion zurückgeben:

%Vor%

Dies ist einfach:

%Vor%     
John Dibling 13.12.2010 15:59
quelle
0

Eine andere Möglichkeit als die Rückgabe einer Referenz ist die Rückgabe eines Zeigers. Wenn das Konto existiert, geben Sie den Zeiger zurück. Andernfalls gebe NULL zurück.

    
rkellerm 13.12.2010 15:44
quelle
0

Es gibt noch einen anderen Weg, der dem "is valid" -Muster ähnlich ist. Ich entwickle gerade eine Anwendung, die eine Menge solcher Sachen enthält. Aber meine IDs können nie kleiner als 1 sein (sie sind alle SERIAL-Felder in einer PostgreSQL-Datenbank), also habe ich nur einen Standardkonstruktor für jede Struktur (oder Klasse in meinem Fall), der id mit -1 und isValid() method initialisiert das gibt wahr zurück, wenn id nicht gleich -1 ist. Funktioniert perfekt für mich.

    
Sergey Tachenov 13.12.2010 16:04
quelle
0

Ich würde tun:

%Vor%

Eine Methode namens get sollte immer das angeforderte Objekt zurückgeben (IMHO). Wenn es nicht existiert, dann ist das eine Ausnahme. Wenn die Möglichkeit besteht, dass etwas nicht vorhanden ist, sollten Sie auch eine Find-Methode bereitstellen, die bestimmen kann, ob das Objekt existiert, damit ein Benutzer es testen kann.

%Vor%

Ich hätte jetzt einen Zeiger verwenden können, anstatt mich um die Erstellung von AccountRef zu kümmern. Das Problem dabei ist, dass Zeiger keine Besitz-Symantiken haben und daher gibt es keine echte Angabe darüber, wer den Zeiger besitzen (und daher löschen) sollte.

Als ein Ergebnis mag ich es, Zeiger in einen Container zu verpacken, der es dem Benutzer erlaubt, das Objekt nur so zu manipulieren, wie ich es auch möchte. In diesem Fall stellt der AccountRef den Zeiger nicht zur Verfügung, so dass es keine Möglichkeit für den Benutzer von AccountRef gibt, das Konto tatsächlich zu versuchen und zu löschen.

Hier können Sie überprüfen, ob AccountRef gültig ist und einen Verweis auf ein Konto extrahieren (vorausgesetzt, es ist gültig). Da das Objekt nur einen Zeiger enthält, ist der Compiler wahrscheinlich, dies zu dem Punkt zu optimieren, dass dies nicht teurer ist, als den Zeiger herumzugeben. Der Vorteil ist, dass der Benutzer nicht versehentlich missbrauchen kann, was ich ihnen gegeben habe.

Zusammenfassung: AccountRef hat keine echten Laufzeitkosten. Aber bietet Typ Sicherheit (wie es die Verwendung von Zeiger versteckt).

    
Martin York 13.12.2010 19:47
quelle
0

Ich mache gerne eine Kombination aus dem, was Sie vorschlagen, mit dem Gültig-Flag und dem, was jemand anderes mit dem Null-Objektmuster vorgeschlagen hat.

Ich habe eine Basisklasse namens Status , die ich von Objekten erhalte, die ich als Rückgabewerte verwenden möchte. Ich werde das meiste aus dieser Diskussion herauslassen, da es etwas komplizierter ist, aber es sieht ungefähr so ​​aus.

%Vor%

Jetzt hättest du

%Vor%

Wenn Sie jetzt ein Konto ohne Parameter erstellen:

%Vor%

Es ist ungültig. Aber wenn Sie ein Konto mit Daten erstellen

%Vor%

Es ist gültig.

Sie testen die Gültigkeit mit dem Operator bool.

%Vor%

Ich mache das sehr oft, wenn ich mit Mathe-Typen arbeite. Ich möchte zum Beispiel keine Funktion schreiben müssen, die so aussieht.

%Vor%

wobei a, b und c Matrizen sind. Ich würde viel lieber schreiben

%Vor%

mit Überladung des Operators. Aber es gibt Fälle, in denen a und b nicht multipliziert werden können, so dass es nicht immer gültig ist. Sie geben einfach ein ungültiges c zurück, wenn es nicht funktioniert, und ich kann

tun %Vor%     
miked 13.12.2010 20:57
quelle
-1

boost :: optional ist wahrscheinlich das Beste, was Sie in einer Sprache tun können, die so kaputt ist, dass sie keine nativen Varianten hat.

    
Yttrill 13.12.2010 15:56
quelle

Tags und Links