Was ist ein Verweis auf einen Zeiger?

8

Ich habe kürzlich eine Funktion gesehen, die folgendermaßen deklariert wird:

%Vor%

Ich kenne den Unterschied zwischen type* param und type& param bereits. Wie unterscheidet sich das obige von ihnen? Und wann sollte man das benutzen? Ist es ratsam, dies zu tun?

    
ReignBough 13.03.2014, 09:42
quelle

2 Antworten

14

Das obige wird in der Lage sein, nicht nur das spitze Objekt, sondern auch den Zeiger selbst zu modifizieren. Betrachten Sie als Beispiel den folgenden Code:

%Vor%

Am Ende der Ausführung hat x den Wert 1 und y ist 0 (wie Sie kann sehen ).

Beachten Sie, dass ich für das Beispiel 0 als Nullzeiger verwendet habe, aber wenn Sie C ++ 11 verwenden, dann sollte wahrscheinlich stattdessen nullptr verwenden (ohne überladene operaror<< für std::ostream ).

Dieses Konzept kann möglicherweise durch einen Blick auf den folgenden Code assimiliert werden:

%Vor%

oder

%Vor%

In diesen Beispielen ist x eine Referenz auf einen Typ ( ptr<int> und dann std::unique_ptr<int> ), was zufällig ein Zeiger / Klasse mit Pointer-Semantik ( operator* und operator-> ) ist.

Ein möglicherweise interessanter Exkurs kann an der Position eines const -Qualifikators im Zeiger vorgenommen werden. Betrachten Sie diese zwei Instanzen:

  1. void func(const int*& ptr)
  2. void func(int*const& ptr)

Ihre Bedeutungen sind:

  1. Zeiger durch Verweis auf eine Konstante int .
  2. Zeiger durch konstanten Verweis auf ein int .

Und nach der obigen Analogie mit ptr wären sie:

  1. ptr<const int>&
  2. ptr<int> const&

Daher kann der erste Befehl *ptr = 1 nicht im Körper der Funktion ausführen (weil int konstant ist), aber wird ptr = 0 gerne ausführen.

Die zweite verhält sich umgekehrt, erlaubt *ptr = 1 (weil das angegebene int nicht konstant ist), während ptr = 0 nicht erlaubt ist (weil der Zeiger konstant ist).

Natürlich im Fall von:

%Vor%

was in der ptr Analogie wäre ptr<const int> const& , beide wären nicht erlaubt.

  

Und wann soll ich das benutzen? Ist es ratsam, dies zu tun?

Wie jedes Feature finden Sie es nützlich, wenn Sie es brauchen. Aber als allgemeine Idee haben einige Leute den Zeiger nach dem Freigeben einer dynamisch zugewiesenen Ressource zurückgesetzt (ich empfehle das nicht, siehe unten).

Nehmen wir das Beispiel:

%Vor%

Am Ende der Ausführung wird x korrekt freigegeben und der Zeiger automatisch auf nullptr gesetzt. (Nullzeiger) Dies wurde getan, um hässliche Segmentierungsfehler oder "Zeiger freigegeben wurde nicht zugeordnet" -Fehlermeldungen, die durch ein fehlendes ptr = nullptr verursacht wurden, zu vermeiden.

Aber mit C ++ 11 und C ++ 14 wird sehr wenig auf Zeiger und noch weniger auf Zeiger zurückgegriffen. Die meisten der Dinge, für die Zeiger verwendet werden, werden nicht durch andere Standardkonstrukte ersetzt (siehe std::optional , < a href="http://en.cppreference.com/w/cpp/memory/unique_ptr"> std::unique_ptr , std::shared_ptr oder std::reference_wrapper zum Beispiel).

    
Shoe 13.03.2014 09:44
quelle
2

Vergleichen wir alle drei Optionen:

  • void func(type* param); // 'param' is a 'type*' variable
  • void func(type& param); // 'param' is a reference to a 'type' variable
  • void func(type*& param); // 'param' is a reference to a 'type*' variable
%Vor%

Natürlich, wenn Sie *param = ... verwenden, wird den Inhalt des Speichers, auf den param zeigt, beeinflussen. Und Sie können zum Beispiel auch param[5] = ... ausführen und andere Bereiche innerhalb dieses Speicherplatzes beeinflussen.

%Vor%

Hier ändern Sie nur die referenzierte Variable selbst . Es ist also sicherer, die Funktion als void func(type* param) zu deklarieren und dann die Adresse von type param zu übergeben, indem Sie func(&param) aufrufen.

%Vor%

Dies ist ähnlich wie die Funktion void func(type** param) zu deklarieren und dann die Adresse von type* param durch Aufruf von func(&param) zu übergeben, aber wiederum ist es aus dem gleichen Grund sicherer.

barak manos 13.03.2014 09:58
quelle

Tags und Links