Ich mache gerade mein erstes richtiges Projekt in C ++ und so, ziemlich neu zu Zeigern. Ich weiß, was sie sind und habe einige grundlegende Nutzungsregeln gelesen. Wahrscheinlich nicht genug, da ich immer noch nicht wirklich verstehe, wann ich sie benutzen soll und wann nicht.
Das Problem ist, dass die meisten Orte nur erwähnen, dass die meisten Menschen sie entweder überbeanspruchen oder zu wenig nutzen. Meine Frage ist, wann man sie benutzt und wann nicht? .
Momentan frage ich mich in vielen Fällen, ob ich hier einen Zeiger verwenden soll oder nur die Variable selbst an die Funktion übergeben soll.
Ich weiß zum Beispiel, dass Sie einen Zeiger auf eine Funktion senden können, so dass die Funktion tatsächlich die Variable selbst anstelle einer Kopie davon ändern kann. Aber wenn Sie nur einmal Informationen über das Objekt erhalten müssen (zum Beispiel benötigt die Methode ein getValue ()), sind Zeiger in diesem Fall nützlich?
Ich würde gerne beide Reaktionen sehen, aber auch Links, die hilfreich sein könnten. Da es das erste Mal ist, dass ich C ++ benutze, habe ich noch kein gutes C ++ - Buch (dachte darüber nach, eines zu kaufen, wenn ich weiterhin c ++ benutze, was ich wahrscheinlich tun werde).
Für die Do's und Dont's von C ++:
Effektives C ++ und effektiveres C ++ von Scott Meyers.
Für Zeiger (und Referenzen):
Verwenden Sie keine rohen Zeiger, wenn Sie dies nicht tun müssen. Die meiste Zeit ist ein intelligenter Zeiger (siehe Boost ) die bessere Option.
1) Ich verwende tendenziell Member-Variablen, die mit der Klasse verknüpft sind. Sie werden im Initialisierer der Klasse konstruiert, und ich brauche mir keine Gedanken über Zeiger zu machen.
2) Sie können durch Verweis auf eine Funktion übergeben werden und müssen sich nicht darum kümmern, Zeiger zu übergeben. Dies übergibt effektiv einen Zeiger auf die Methode / Funktion, die verwendet werden kann, als ob Sie die Klasse übergeben hätten, aber ohne den Aufwand, die Klasse selbst zu kopieren.
3) Wenn ich die Lebensdauer eines Objekts steuern muss, das unabhängig von den Klassen meiner Hauptanwendungsarchitektur ist, dann benutze ich ein auto_ptr von der STL, um die Zerstörung des Zeigers automatisch zu handhaben, wenn niemand länger darauf verweist. Schau es dir an - es ist der richtige Weg.
Verwenden Sie es immer dann, wenn Sie mit zugeordnetem Speicher arbeiten oder Argumente mit Bezug auf eine Methode übergeben; Ich glaube nicht, dass es eine Regel gibt, keine Zeiger zu verwenden.
Meine Faustregeln:
NULL
-Zeiger übergeben können (gelten Sie für # 1 und # 3) pass per const T*
oder per T*
) Streams müssen immer als nicht konstante Referenzen weitergegeben werden.
Wenn Sie Verweise anstelle von Zeigern verwenden können, ist es im Allgemeinen eine gute Idee. Eine Referenz muss ein Ziel haben (keine NULL-Pointer-Verletzungen), sie erlauben dieselbe Semantik wie Zeiger, wenn sie als Argumente an eine Funktion übergeben werden, und sie sind im Allgemeinen besser für Anfänger (oder solche, die nicht von einem C-Hintergrund kommen) / p>
Zeiger sind erforderlich, wenn Sie dynamische Speicherzuweisung vornehmen möchten. wenn Sie mit einer unbekannten Menge von Dingen umgehen müssen, die später spezifiziert werden. In diesem Fall erfolgt die Schnittstelle zum Zugriff auf den Speicher über new
und delete
, die Zeiger enthalten.
Meine Philosophie besteht darin, immer Wert zu übergeben, es sei denn, Sie müssen die übergebene Variable ändern oder das Kopieren des Objekts ist teuer. In beiden Fällen sollten Sie zuerst einen Verweis anstelle eines Zeigers verwenden: Wenn Sie nicht ändern müssen, auf welches Objekt Sie verweisen, oder einen möglichen Extremwert (NULL-Zeiger) benötigen, können Sie einen Verweis verwenden.
Vergessen Sie auch nicht die Iteratoren.
Alle guten Antworten oben. Wenn Sie eine rechenintensive Arbeit ausführen, ist es außerdem wichtig zu wissen, dass das Dereferenzieren eines Zeigers wahrscheinlich ein Cache-Fehltreffer auf Ihrem Prozessor ist. Es ist eine gute Idee, Ihre Daten mit minimalen Zeigerdereferenzen verfügbar zu halten.
Verhindern Sie auf diese Weise Speicherlecks und kontrollieren Sie die Konsistenz des Attributs.
Salu2.