2012-04-09 10 views
2

Mögliche Duplizieren:
C++: When to use References vs. PointersWarum und wo Referenz- und Zeiger in C++

Ich bin ziemlich neu Programmierer auf die C/C++ Sprachen und da ich aus einem komme Hintergrund von C#, Java, JavaScript und ein wenig von Visual Basic und Python, ich habe eine harte Zeit, einige der Dinge in C++ zu verstehen.

Ich weiß bereits, wie man Referenz und Zeiger verwendet und was sie wirklich bedeuten usw. Aber ich verstehe nicht, warum und wo man sie benutzt. Ich weiß, dass Referenzen manchmal wie folgt verwendet werden:

int x = 2; 

void Square(int &value) 
{ 
    value = value*value; 
} 

Square(x); 

cout << x << endl; 

Und die Ausgabe 4.

sein Ich dachte, ich verstehe nicht ganz, warum es so zu tun und nicht tun, wie folgt:

Wie auch immer, ich hoffe, jemand kann mir helfen zu verstehen, warum und wo Referenz und Zeiger zu verwenden.

Antwort

3

Sie passieren Referenzen für zwei Hauptgründe:

  • den Wert der in Ihrer Funktion
  • referenzierte Objekt zu ändern, um die Kosten für das Kopieren des Objekts zu vermeiden, übergeben Sie

Wenn Sie Möchten Sie den zweiten Vorteil, aber nicht den ersten, übergeben Sie in der Regel eine const Referenz, um zu vermeiden, versehentlich das übergebene Objekt zu ändern.

In C++, Zeiger und Referenzen sind sich sehr ähnlich, mit zwei Ausnahmen:

  • ein Bezugspunkt kann nicht auf 0 (oder nullptr)
  • Ein Verweis immer auf das gleiche Objekt zeigen muss

Wenn Sie eines dieser Dinge tun möchten, müssen Sie einen Zeiger verwenden.

Außerdem zeigen Zeiger normalerweise auf Objekte, die im Heap erstellt wurden, indem new verwendet wird, während Referenzen normalerweise auf Objekte verweisen, die im Stapel erstellt wurden. Dies bedeutet, dass die Lebensdauer von Objekten, auf die Zeiger zeigen, normalerweise manuell gesteuert wird. Sie müssen delete explizit für Objekte aufrufen, die von new erstellt wurden, um sie zu zerstören, aber die Lebensdauer der im Stack erstellten Objekte wird automatisch von der Laufzeitumgebung verwaltet (daher der Name "automatische Variablen").

Ich weiß nicht, ob das alles ist, was Sie wissen müssen, oder Sie suchen nach etwas Spezifischerem.

+0

Danke das ist mir sehr geholfen! – UnTraDe

+2

Bemerkenswert, dass ein sehr häufiger Fehler C++ Programmierer zu beginnen Zeiger verwendet, wo sie eine Referenz verwenden könnten (und sollten) Heap mit neuen, wenn Sie müssen, und nicht übergeben Zeiger (verwenden Sie Referenzen), wenn Sie müssen – Ricibob

+0

Ok, ich werde versuchen, dies im Hinterkopf zu behalten – UnTraDe

0

Das zweite Beispiel wird lokal Ihre Variable kopieren x (nur sichtbar innerhalb Square Funktion).

Wenn Sie sicherstellen möchten, dass Ihr globales x unverändert bleibt, tun Sie es so. Es kann jedoch teuer sein (wenn Ihre Variable größer Objekt/Struktur ist) ... und redundant - überprüfen Sie Stichwort const.

+0

Danke! Nur um sicher zu sein, durch teure meinen Sie kosten mehr Speicher oder? – UnTraDe

+0

Nicht nur, 'CPU' auch – IProblemFactory

+0

Ok vielen Dank! – UnTraDe

0

Argument als Verweis übergeben bedeutet, dass Sie den Wert ändern (wenn Sie eine Operation ausführen) und nicht eine Variable, die eine Kopie davon ist. Da Sie den Wert & verwenden, wird der Inhalt geändert, der unter der Adresse & Wert gespeichert ist.

Und Sie müssen & x anstelle von x in Squre() übergeben.

So x = Squre (& x);

oder

Squre (& x);

ist gleich.

+0

Danke! Aber x = Squre (&x); ist nicht unwirksam? – UnTraDe

0

Ein Verweis ist nur ein Pseudoname für eine Variable. Jede angelegte Aktion auf eine Referenz Auswirkungen tatsächlich die Variable, die Sie beziehen sich auf

int a = 5; 
int &b = a; 
b++; // 'a' gets equal to 6 

In Ihrem Beispiel Sie das Ergebnis der Multiplikation zurück, aber was ist, wenn Sie benötigen Wert einer Variablen an eine Funktion übergeben ändern, die nichts zurückgibt?

Dies ist, wenn Referenzen handlich werden. Ein Zeiger verhält sich ähnlich, außer dass der Zeiger kein Pseudoname für eine Variable ist, sondern seine Adresse. Sie könnten einen Zeiger auf eine Variable an eine Funktion übergeben, ihn dereferenzieren, und er würde Ihre Variable auf genau die gleiche Weise beeinflussen.

+0

Danke! Ich weiß bereits, was Sie in dem Beispiel gesagt haben, aber ich nicht wirklich verstanden, warum es nützlich ist.Nur für die Speicherverwaltung? – UnTraDe

1

Es gibt keinen praktischen Unterschied für ein Beispiel wie dieses, aber anstatt eine ganze Zahl an Square() zu übergeben, war imagine square ein komplexer Algorithmus, der 10 Gigabytes an Daten benötigte. Wäre es nicht besser, einen Zeiger zu verwenden, damit der Parameter nicht kopiert wird?

+0

Danke! Sie sagen also, dass es nur mit der Speicherverwaltung zusammenhängt? – UnTraDe

+0

Es ist einfach schneller, weil der Compiler keine Kopie des Arguments erstellt. –

0

Nun, für POD Strukturen, werden Sie nicht viele Vorteile sehen, weil die Operation = ist einfach zu verstehen.

Also Ihr tut ziemlich, was es sagt, mit ziemlich guter Leistung.

Der Vorteil der Verwendung eines Zeigers/Verweises entsteht, wenn Sie Objekte an Ihre Methoden übergeben. In diesem Fall:

Object x; 

Object squre(Object x) 
{ 
    x._internalvalue = x._internalvalue * x._internalvalue; 
    return x; 
} 

x = squre(x); 

Die Prozesse hier unter völlig anders: Die = Zeichen nichtautomagically auf Objekte angewendet wird, so dass Sie implementieren müssen werde, was die rule of three genannt wird, in dem Sie Ich werde einen Zuweisungsoperator finden. Der Zuweisungsoperator ist jedoch ziemlich teuer, da er ein neues (temporäres) Objekt im Speicher neu erstellen muss, den Zuweisungsoperator aufrufen und dann den Speicher dieses Objekts zurück auf das ursprüngliche x kopieren muss.

Wenn ein Objekt als Argument einer Funktion übergeben wird, wird der Prozessor gezwungen, den gesamten von diesem Objekt auf dem Stapel belegten Speicher zu kopieren, um in der Funktion Zugriff darauf zu haben, was sehr kostspielig ist.

Also, um Ihre Frage zu beantworten, fangen Sie an, die Vorteile der Verwendung von Referenzen und Zeigern zu sehen, wenn Sie beginnen, Strukturen und Objekte zu manipulieren, die WAY größer als einfache alte ganze Zahlen sind.

Programmieren mit Referenzen wird Ihnen einen Schub von Leistungen geben und die Risiken eines Stapelüberlaufs begrenzen, wenn Sie große Objekte manipulieren.

+0

Ok aber was passiert zum Beispiel auf C# Ich weiß, du hast ref und out oder s so etwas, aber ich kann mich nicht erinnern, dass ich es irgendwo gesehen habe. Oder vielleicht sah ich es und vergaß es einfach. – UnTraDe

0

Referenz wird verwendet, wenn Sie auf eine Variable mit einem anderen Namen verweisen möchten. Sie haben genau den gleichen Typ, Wert usw.
Pointer ist etwas anders, es ist ein neuer Typ, um die Adresse zu speichern.

int i; 
Int &ref = i; 
Int *pointer = &i; 

Dann ref und * Zeiger ist in der Tat die gleiche Sache, der Wert von i.
Aber Sie müssen wissen, dass das Literal "Ref" ist nur "i" (es kann nie nach der Initialisierung ändern), aber "Zeiger" nur vorübergehend auf i zeigt.
Also in den meisten Fällen sind sie das Gleiche.
Wann verwenden wir dann Referenz oder Zeiger?
Meiner Meinung nach, was bequemer ist.
Zum Beispiel kann eine Referenz nicht geändert werden, aber ein Zeiger ein Punkt auf verschiedene Dinge.^_^ Ah, ich vergesse die Kosten für das Kopieren, überprüfen Sie bitte die Antworten des anderen.

+0

Danke für die Antwort! – UnTraDe