Frage

Was wäre eine bessere Vorgehensweise, wenn einer Funktion die ursprüngliche Variable zugewiesen werden soll, mit der sie arbeiten soll:

unsigned long x = 4;

void func1(unsigned long& val) {
     val = 5;            
}
func1(x);

oder:

void func2(unsigned long* val) {
     *val = 5;
}
func2(&x);

IOW:Gibt es einen Grund, das eine dem anderen vorzuziehen?

War es hilfreich?

Lösung

Meine Faustregel gilt:

Verwenden Sie Zeiger, wenn Sie mit ihnen Zeigerarithmetik tun wollen (zum Beispiel der Zeigeradresse erhöht wird durch eine Anordnung zum Schritt) oder wenn Sie jemals einen NULL-Zeiger übergeben.

Verwenden Sie Verweise auf andere Weise.

Andere Tipps

Ich glaube wirklich, Sie zur Gründung der folgenden Aufruf der Funktion Code-Richtlinien profitieren:

  1. Wie bei allen anderen Orten, immer const korrigieren werden.

    • . Hinweis: Das bedeutet unter anderem, dass nur out-Werten (siehe Punkt 3) und nach Wert übergebenen Werten (siehe Punkt 4) kann den const Spezifizierer fehlt
  2. Nur einen Wert, der durch Zeiger übergeben, wenn der Wert 0 / NULL eine gültige Eingabe im aktuellen Kontext ist.

    • Rationale. 1: Wie ein Anrufer , Sie sehen, dass das, was Sie passieren in muss in einem nutzbaren Zustand

    • Rationale 2: Wie Namen , Sie wissen, dass das, was kommt in ist in einem nutzbaren Zustand. Daher muss kein NULL-Check oder die Fehlerbehandlung für diesen Wert zu tun.

    • Rationale 3: Rationales 1 und 2 wird Compiler erzwungen . fängt immer Fehler bei der Kompilierung, wenn Sie können.

  3. Wenn ein Funktionsargument einen Out-Wert ist, dann gibt sie Bezug genommen wird.

    • Begründung: Wir wollen nicht, Punkt 2 brechen ...
  4. Wählen Sie "Wert übergeben" über "durch const Verweis übergeben" nur dann, wenn der Wert ein POD ( Plain alte Datenstruktur ) oder klein genug (Speicher-weise) oder auf andere Weise billig genug (zeitweise) zu kopieren.

    • Begründung: Vermeiden Sie unnötige Kopien
    • .
    • . Hinweis: klein genug und billig genug sind nicht absolute Messgrößen

Dies führt schließlich endet subjektiv. Die Diskussion so weit ist nützlich, aber ich glaube nicht, gibt es eine richtige oder entscheidende Antwort auf diese. Viel wird davon abhängen, Stilrichtlinien und Ihre Bedürfnisse zu der Zeit.

Zwar gibt es einige unterschiedlichen Fähigkeiten (auch nicht etwas, kann NULL sein) mit einem Zeiger, der größte praktische Unterschied für einen Ausgabeparameter ist rein Syntax. Googles C ++ Style Guide ( https://google.github.io/styleguide/cppguide.html# Reference_Arguments ), beispielsweise Mandate nur Zeiger für Ausgabeparameter und erlaubt nur Referenzen, die const sind. Die Argumentation ist eine der Lesbarkeit: etwas mit Wert Syntax nicht Zeiger semantische Bedeutung haben sollte. Ich schlage nicht vor, dass dies unbedingt richtig oder falsch ist, aber ich denke, der Punkt hier ist, dass es eine Frage des Stils ist, nicht von Richtigkeit.

Sie sollten einen Zeiger übergeben, wenn Sie den Wert der Variablen ändern gehen. Obwohl technisch eine Referenz oder ein Zeiger vorbei gleich ist, einen Zeiger in Ihrem Gebrauch vorbei Fall ist besser lesbar, da es „wirbt“ die Tatsache, dass der Wert durch die Funktion geändert werden.

Wenn Sie einen Parameter haben, wo Sie müssen möglicherweise das Fehlen eines Wertes, um anzuzeigen, ist es gängige Praxis der Parameter ein Zeigerwert und übergeben Sie NULL zu machen.

Eine bessere Lösung in den meisten Fällen (aus sicherheitstechnischer Sicht) ist boost :: optional . Auf diese Weise können Sie in optionalen Werten durch Verweis übergeben und auch als Rückgabewert.

// Sample method using optional as input parameter
void PrintOptional(const boost::optional<std::string>& optional_str)
{
    if (optional_str)
    {
       cout << *optional_str << std::endl;
    }
    else
    {
       cout << "(no string)" << std::endl;
    }
}

// Sample method using optional as return value
boost::optional<int> ReturnOptional(bool return_nothing)
{
    if (return_nothing)
    {
       return boost::optional<int>();
    }

    return boost::optional<int>(42);
}

Referenz verwenden, wenn Sie können, einen Zeiger verwenden, wenn Sie zu haben. Aus C ++ FAQ: „Wann soll ich Referenzen verwenden, und wann sollte ich Zeiger verwenden“

Hinweise

  • Ein Zeiger ist eine Variable, die eine Speicheradresse enthält.
  • Eine Zeigerdeklaration besteht aus einem Basistyp, einem * und dem Variablennamen.
  • Ein Zeiger kann auf eine beliebige Anzahl von Variablen während der Lebensdauer zeigen
  • Ein Zeiger, der derzeit nicht auf einen gültigen Speicherort zeigt, erhält den Wert null (was Null ist).

    BaseType* ptrBaseType;
    BaseType objBaseType;
    ptrBaseType = &objBaseType;
    
  • Das & ist ein unärer Operator, der die Speicheradresse seines Operanden zurückgibt.

  • Der Dereferenzierungsoperator (*) wird verwendet, um auf den in der Variablen gespeicherten Wert zuzugreifen, auf den der Zeiger zeigt.

       int nVar = 7;
       int* ptrVar = &nVar;
       int nVar2 = *ptrVar;
    

Referenz

  • Eine Referenz (&) ist wie ein Alias ​​für eine vorhandene Variable.

  • Eine Referenz (&) ist wie ein konstanter Zeiger, der automatisch dereferenziert wird.

  • Es wird normalerweise für Funktionsargumentlisten und Funktionsrückgabewerte verwendet.

  • Eine Referenz muss beim Erstellen initialisiert werden.

  • Sobald ein Verweis auf ein Objekt initialisiert wurde, kann er nicht mehr geändert werden, um auf ein anderes Objekt zu verweisen.

  • Sie können keine NULL-Referenzen haben.

  • Eine const-Referenz kann sich auf einen const int beziehen.Dies geschieht mit einer temporären Variablen mit dem Wert const

    int i = 3;    //integer declaration
    int * pi = &i;    //pi points to the integer i
    int& ri = i;    //ri is refers to integer i – creation of reference and initialization
    

enter image description here

enter image description here

Eine Referenz ist ein impliziter Zeiger. Grundsätzlich können Sie den Wert der Referenzpunkte ändern, aber Sie können nicht den Hinweis auf etwas anderes Punkt ändern. So ist meine 2 Cent ist, dass, wenn Sie den Wert eines Parameters als Referenz übergeben ändern wollen, aber wenn Sie den Parameter ändern müssen, auf ein anderes Objekt zeigen geben sie einen Zeiger verwenden.

Betrachten C # 's out-Schlüsselwort. Der Compiler muss den Aufrufer einer Methode, um das Schlüsselwort out auf alle aus args anzuwenden, auch wenn es bereits weiß, wenn sie sind. Damit soll die Lesbarkeit verbessern. Obwohl mit modernem IDEs zu denken, ich bin geneigt, dass dies eine Aufgabe für Syntax (oder semantische) hervorzuheben.

Sie passieren konstante Referenz, es sei denn es einen Grund, Sie wollen den Inhalt ändern / halten Sie vorbei sind.

Dies wird die effizienteste Methode in den meisten Fällen sein.

Stellen Sie sicher, dass Sie const auf jeden Parameter verwenden Sie möchten von Ihnen nicht geändert werden, da dies nicht nur schützt, etwas Dummes in der Funktion zu tun, es gibt einen guten Hinweis für andere Benutzer, was die Funktion der in Werte übergeben hat. Dies schließt einen Zeiger const machen, wenn Sie wollen nur was ändern deutete auf ...

Pointers:

  • Kann zugewiesen nullptr (oder NULL).
  • Am Aufrufort, müssen Sie & verwenden, wenn Ihr Typ kein Zeiger selbst ist, machen explizit modifizieren Sie Ihr Objekt.
  • Pointers kann Rebound sein.

Referenzen:

  • Kann nicht null sein.
  • Einmal gebunden, kann nicht geändert werden.
  • Anrufer müssen nicht explizit & verwenden. Dies wird manchmal schlecht, weil Sie zur Implementierung der Funktion gehen müssen, um zu sehen, ob Ihre Parameter geändert wird.

Eine Referenz ist ähnlich einen Zeiger, mit der Ausnahme, dass Sie nicht brauchen, einen Präfix * zu verwenden, um den Wert von der genannten Referenz zuzugreifen. Auch kann ein Verweis, der nicht auf ein anderes Objekt gemacht wird, nach der Initialisierung beziehen.

Referenzen sind besonders nützlich, Funktionsargumente für angeben.

Weitere Informationen finden Sie unter "Eine Tour durch C ++" von "Bjarne Stroustrup" (2014) Seiten 11-12

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top