2009-04-14 19 views

Antwort

20

Die & Version stellt eine Referenz dar, während die * Version einen Zeiger darstellt. Der Unterschied ist viel zu groß für einen typischen SO Post. Ich schlage vor, Sie bei der C++ FAQ starten lite

http://www.parashift.com/c++-faq-lite/references.html

ich in der Regel nicht mag Beiträge mit einer beantworten Antwort „Sie Google verwenden sollten“. Dies ist jedoch ein Thema, das ich Ihnen sehr rate google. Insbesondere google "C++ Zeiger vs. Referenzen". Es gibt eine Fülle von Informationen zu diesem Thema und die Diskussionen auf diesen Seiten werden alles übertrumpfen, was wir hier schreiben werden.

+1

Ich denke, Joel und Jeff würden sich freuen, wenn jemand, der Google benutzt, um diese Frage zu beantworten, auf eine StackOverflow-Seite weitergeleitet und von einem StackOverflow-Werbetreibenden beeindruckt wurde. –

+3

Ja, ich weiß, das ist alt. Aber ich bin auf dieser Seite nach einer Google-Suche nach "Unterschied zwischen Referenz und Zeiger" gelandet. Es war Ergebnis # 3. – Ross

+2

ugh, ich habe es gegoogelt und bin hierher gekommen ... Genau die gleiche Frage, die ich habe. –

5

Eine Klasse * kann auf beliebige Klassenobjekte oder keine zeigen.

Eine Klasse & zeigt immer auf genau ein Klassenobjekt und kann niemals auf ein anderes Objekt zeigen.

Außerdem glaube ich, Bjarne ein Mitglied der Gruppe von Menschen, die „Arrays in C gebrochen ist nicht mehr zu reparieren“, eine Klasse * bei einem ganzen ding-dingt zeigen kann Array von Klassenobjekten behauptet haben, aufgereiht einer nach dem anderen im Speicher, und in C gibt es absolut keine Möglichkeit zu sagen, ob eine Klasse * auf einen oder viele Punkte zeigt.

6

Der * ist ein Zeiger, der & ist eine Referenz. Der Unterschied zwischen den beiden ist, dass ein Zeiger ein Bereich des Speichers ist, der dereferenziert werden muss, z. mit dem Operator ->, um als Klasseninstanz "gesehen" zu werden. Ein Verweis ist stattdessen ein "Alias", nur ein alternativer Name für dieselbe Klasseninstanz. Sie müssen den Operator -> nicht mit einer Referenz verwenden. Sie verwenden den Punktoperator.

Persönlich habe ich selten die Referenzen verwendet, vor allem, wenn ich ein Wertobjekt hatte, das ich auf dem Stack zugewiesen habe. Der neue Operator gibt immer einen Zeiger zurück, den Sie dann dereferenzieren müssen. Darüber hinaus ist eines der problematischsten Probleme der Referenzen, dass Sie sie nicht auf NULL setzen können. In einigen Fällen ist es praktisch, eine Funktion zu haben, die entweder einen Objektzeiger oder NULL akzeptiert. Wenn Ihre Funktion eine Referenz akzeptiert, können Sie keine NULL übergeben (Sie könnten jedoch auch das Null-Objektmuster verwenden).

+0

Natürlich sind Null-Zeiger eine große Quelle von Fehlern in C++, daher denke ich nicht, dass Referenzen in dieser Hinsicht schlecht sind. –

0

Ein weiterer Unterschied besteht darin, dass Referenzvariablen initialisiert werden müssen. Sie können keine Referenzvariable wie im Beispielcode erstellen. Das würde einen Compilerfehler erzeugen.

0

Eine Referenz (&) ist genau das gleiche wie ein Zeiger (*), außer dass der C++ - Compiler sicherstellt, dass er nicht NULL ist. Es kann jedoch immer noch ein Dangling-Zeiger sein (eine Zeigervariable, die keine Referenz hat, so dass sie nicht verwendet werden kann und für jede Verwendung ungültig ist).

0

Wie bereits erwähnt, sollten Sie es googeln, aber Missverständnisse zu vermeiden:

  • Referenzen sind NICHT Variablen
  • Referenzen sind nicht vergleichbar mit Zeiger (aber man kann sie in ähnlicher Weise verwenden)

Denken Sie an eine Referenz als Abkürzung für den Begriff, der ihm zugewiesen ist.

0

Ein weiterer Tipp, den ich bieten würde, ist die folgende:

Verwenden Referenzen, wenn Sie können, Zeiger, wenn Sie zu haben. Wenn das Objekt garantiert existiert, sollten Sie wahrscheinlich eine Referenz verwenden. Wenn dies nicht der Fall ist, müssen Sie wahrscheinlich einen Zeiger verwenden.

Ein weiterer Vorteil ist, dass Referenzen Mehrdeutigkeit bei der Eigentümerschaft entfernen. Sobald ein Wartungsprogrammierer einen Zeiger sieht, werden sie sich fragen, ob sie ihn löschen sollen.

prüfen dieses Beispiel aus:

 
// Wrapper class using a reference because the wrapped object always exists 
class Wrapper 
{ 
public: 
    // If the wrapped is guaranteed to exist at creation, do it this way 
    Wrapper(Wrapped& wrapped):_wrapped(wrapped) { /* empty */ } 

    // put extra methods here. 
    int getWrappedValue() const { return _wrapped.getValue(); } 

private: 
    Wrapped& _wrapped; // This object always exists and is valid 
}; 

// Wrapper class written to support a possibly non-existent wrapped object. 
class Wrapper 
{ 
public: 
    Wrapper(Wrapped* wrapped = 0):_wrapped(wrapped) { /* empty */ 

    void setWrappee(WRappee* wrapped) { _wrapped = wrapped; } 

    int getWrappedValue() const; // Not making inline -- more complex 

private: 
    Wrapped* _wrapped; // Always check pointer before use 
}; 

int Wrapper::getWrappedValue() const 
{ 
    if (_wrapped) 
    { 
    return _wrapped->getValue(); 
    } 
    else 
    { 
    return -1; // NOTE, this is a contrived example -- not getting into exceptions 
    } 
} 
Verwandte Themen