In " Andere C ++ - Funktionen", "Referenzargumente" des Google C ++ - Stilhandbuchs , habe ich gelesen, dass Verweise, die keine Konstanten sind, nicht verwendet werden dürfen.
Alle als Referenz übergebenen Parameter müssen mit const gekennzeichnet sein.
Es ist klar, dass das Betrachten von Funktionsaufrufen, die Referenzen als Argumente verwenden, für C-Programmierer absolut verwirrend ist, aber C und C ++ sind jetzt verschiedene Sprachen. Wenn ein Ausgabeparameter erforderlich ist , kann die Verwendung eines Zeigers für einen erforderlichen Ausgabeparameter dazu führen, dass der gesamte Funktionskörper übersprungen wird, was die Implementierung einer Funktion komplizierter macht (was die zyklomatische Komplexität und Tiefe einer Funktion formal erhöht ).
Ich möchte, dass C ++ - Code so einfach wie möglich zu verstehen und zu warten ist. Daher bin ich generell daran interessiert, Coding-Style-Guides zu lesen. Um die Best Practices in einem Team anzupassen, ist es meiner Meinung nach ein wichtiger Faktor, die Hintergründe der Style-Guide-Elemente zu verstehen.
Sind nicht konstante Referenzen wirklich so schlecht? Ist das Verbot nur Google-spezifisch oder eine allgemein akzeptierte Regel? Was rechtfertigt den zusätzlichen Aufwand für die Implementierung von Ausgabeparametern als Zeiger?
Antworten:
Das Grundprinzip hinter Googles Styleguide besteht einfach darin, auf der Aufrufseite einer Funktion zu verdeutlichen, ob ein Parameter ein Eingabeparameter oder ein Ausgabeparameter ist. ( Weitere Informationen hierzu finden Sie hier .) Andere Sprachen weisen Parameter auf, die ausdrücklich vorgesehen sind. C # hat beispielsweise ein
out
Schlüsselwort, das auf der Anrufseite verwendet werden muss . Da C ++ es nicht explizit macht, hat Google const ref gewählt. versus Zeiger, um es deutlich zu machen.Ist das nur eine Google-Regel? Nein, aber ich bezweifle, dass es sehr verbreitet ist. Ich glaube nicht, dass ich es außerhalb des Google Style Guides und von Gruppen gesehen habe, die explizit Teile des Google Style Guides befolgen. (Zum Beispiel hat mir die Idee gefallen, als ich vor Jahren den Google Style Guide zum ersten Mal gelesen habe und ihn für einen Teil meines eigenen Codes verwendet habe.)
Insbesondere die neu angekündigten C ++ Core Guidelines bevorzugen Rückgabewerte als Ausgabeparameter für (fast) alles und verwenden im Übrigen Nicht-Konstanten-Refs. Googles Verwendung von Zeigern im Vergleich zu Referenzen macht die Ausgabeparameter möglicherweise klarer, die Rückgabewerte sind jedoch noch deutlicher. Da C ++ 11 standardisierte Schritte (rWert-Referenzen,
&&
um Rückgaben vieler Typen kostengünstig zu machen) und Tupel (die auf einfache Weise die Rückgabe mehrerer Werte ermöglichen) enthält, gelten viele der Anwendungsfälle für out-Parameter nicht mehr.Die C ++ Core Guidelines haben einige große Namen (Bjarne Stroustrup, Herb Sutter) hinter sich, werden von Microsoft unterstützt und umfassen die neuesten C ++ - Funktionen (im Gegensatz zu Googles Style Guide), daher erwarte ich, dass die Empfehlungen bekannter sind als die von Google.
quelle
Es gibt 2 Möglichkeiten, um mit einem ungültigen Zeiger umzugehen, zuerst zu prüfen und vorzeitig zurückzukehren oder es sich um undefiniertes Verhalten zu handeln (wenn Sie mehr Wert auf Geschwindigkeit als auf Robustheit legen).
Das Prüfen ist so einfach wie:
Diese Art der Prüfung wird allgemein als Parameterprüfung akzeptiert. Wenn Sie den Code sehen, ist es ziemlich klar, dass Sie erwarten, dass ein Zeiger ungleich Null übergeben wird, und wenn nicht, früh zurückkehren. So können Sie sich weniger Gedanken über ungültige Zeiger machen.
quelle
assert(buffer);
wissen, dass die Zusicherung nur für die Debug-Version aktiv ist. Manchmal möchte ich eine habenrt_assert(buffer);
, die eine Ausnahme auslöst. Die Einrückungreturn
sieht ein wenig gefährlich aus ... Übrigens: Ihr Code-Snippet ist ein gutes Beispiel für meine Frage nach Zeigern für die Ausgabe.Es kommt auf Ihre Beobachtung an
If an output parameter is required
.Die einzige Stelle, an der für eine Funktionssignatur ein Ausgabeparameter erforderlich ist, ist die Angabe durch eine externe API. In diesem Fall müssen Sie die externe API nur so einschließen, dass sichergestellt ist, dass immer ein gültiger Pointee vorhanden ist.
Intern vermeiden Sie Ausgabeparameter, indem Sie den Rückgabetyp so erweitern, dass er aus allen "Outs" besteht.
quelle
The only place where...
wirklich auf alle Fälle anwendbar ist. Was Sie vorschlagen, sieht so aus: Vermeiden Sie Ausgabeparameter in den Funktionen Ihrer eigenen Programme. Richtig für neue Programme.