Der Google C ++ - Stilleitfaden unterscheidet deutlich (gefolgt von cpplint.py ) zwischen Eingabeparametern (→ const ref, Wert) und Eingabe-Ausgabe- oder Ausgabeparametern ( → nicht konstante Zeiger):
Parameter zu C / C ++ - Funktionen werden entweder in die Funktion output eingegeben von der Funktion oder von beiden. Eingabeparameter sind normalerweise Werte oder const Referenzen, während Ausgang und Input / Output-Parameter sein werden Nicht-Const-Zeiger.
Und weiter:
Tatsächlich ist es in Google-Code eine sehr starke Konvention, dass Eingabeargumente Werte oder Const-Referenzen sind, während Ausgabeargumente Zeiger sind.
Aber ich kann nicht herausfinden, warum Eingabe- / Ausgabeargumente (ich lasse Ausgabeargumente beiseite) nicht als Referenz übergeben werden sollten. Auf stackoverflow gibt es viele Themen zu dieser Frage: z. hier , die akzeptierte Antwort sagen das eindeutig
Es geht hauptsächlich um Stil
aber das wenn
Sie können Null übergeben, Sie müssen einen Zeiger verwenden
Also, was ist der Punkt für immer , der einen Zeiger verlangt, wenn ich vermeiden möchte, dass der Zeiger null ist? Warum nur Referenzen für Eingabeargumente verwenden?
Der Grund dafür, dass Ausgabeparameter als Zeiger übergeben werden müssen, ist einfach:
Es macht an der Aufrufseite klar, dass das Argument möglicherweise mutiert wird:
%Vor%Wenn sich eine Codebasis entwickelt und inkrementellen Änderungen unterzieht, die von Personen überprüft werden, die möglicherweise nicht den gesamten Kontext kennen, ist es wichtig, den Kontext und die Auswirkungen einer Änderung so schnell wie möglich zu verstehen. Mit dieser Stilregel wird sofort klar, ob eine Änderung eine Mutation einführt.
Der Punkt, den sie machen (dem ich nicht zustimme) ist, dass ich eine Funktion habe
%Vor% Wenn das Argument b
optional ist oder manchmal unnötig ist, können Sie die Funktion wie folgt aufrufen
Wenn die Funktion als
deklariert wurde %Vor% Dann gibt es keine Möglichkeit, nicht in Bar
zu übergeben.
Dieser Punkt (Hervorhebung von mir) ist völlig meinungsbezogen und liegt im Ermessen des Entwicklers.
Tatsächlich ist es im Google-Code eine sehr starke Konvention, dass Eingabeargumente Werte oder Const-Referenzen sind, während Ausgabeargumente Zeiger sind .
Wenn ich beabsichtige, dass b
ein Ausgabeparameter ist, dann sind beide der folgenden Punkte absolut gültig und sinnvoll.
Du bist die erste Frage: "Also, was ist der Punkt an immer , um einen Zeiger zu verlangen, wenn ich vermeiden möchte, dass der Zeiger null
ist?"
Mit einem Zeiger wird dem Aufrufer mitgeteilt, dass seine Variable geändert werden kann. Wenn ich foo(bar)
anrufe, wird bar
geändert? Wenn ich foo(&bar)
aufruft, ist klar, dass der Wert von bar
geändert werden kann.
Es gibt viele Beispiele für Funktionen, die ein null
enthalten, das einen optionalen Ausgabeparameter angibt (aus der Kopfspitze heraus time
ist ein gutes Beispiel.)
Ihre zweite Frage: "Warum nur Referenzen für Eingabeargumente verwenden?"
Das Arbeiten mit einem Referenzparameter ist einfacher als das Arbeiten mit einem Zeigerargument.
%Vor%Dieser mit einer Referenz neu geschriebene Code sieht folgendermaßen aus:
%Vor% Sie können sehen, dass die Verwendung von const int& input
den Code vereinfacht.
Sie verwenden es wahrscheinlich zur Konsistenz, weil sie Ausgabeparameter sowohl als Referenzen auf den vorhandenen Speicher (sie verändern zuvor initialisierte Variablen) als auch als tatsächliche Ausgaben verwenden (die Ausgabeargumente werden von der Funktion selbst zugewiesen). Aus Gründen der Konsistenz verwenden sie es als eine Möglichkeit, Eingänge und Ausgänge deutlicher anzuzeigen.
Wenn Sie eine Funktion / Methode nicht benötigen, um den Speicher des Ausgabeparameters zuzuordnen, z. B. um einen Zeiger aus einem Nachschlag zu löschen oder Speicher zuzuordnen und ihn durch einen Zeiger zurückzugeben, verwenden Sie Verweise. Wenn Sie dies tun müssen, aber nicht darauf achten, Zeiger als Hinweis darauf zu verwenden, ob ein Parameter ein- oder ausgegeben wird, verwenden Sie gegebenenfalls Referenzen für Ausgabeparameter. Es gibt keine absolute Anforderung, Zeiger in allen Fällen zu verwenden, es sei denn, die Anforderungen dieser Funktion / Methode selbst erfordern dies.
Tags und Links c++ reference parameters google-style-guide cpplint