Verwendung von rohen Zeigern im modernen C ++ - Post C ++ 11 [geschlossen]

7

Was sind einige der Hauptgründe für die Verwendung von rohen Zeigern im Jahr 2014, angesichts der Tatsache, dass der C ++ 11-Standard jetzt von den meisten anständigen Compilern gut unterstützt wird?

Ich habe ein paar Szenarien identifiziert:

  1. Sie erweitern eine ältere Codebase, die rohe Zeiger stark verwendet, und möchten die Konsistenz im Stil beibehalten.

  2. Sie verwenden eine Bibliothek, die nur rohe Zeiger exportiert, aber ich schätze, Sie könnten immer noch Umwandlungen verwenden.

  3. Sie möchten die Fähigkeit von Zeigern ausnutzen, mehrere Dereferenzierungsebenen bereitzustellen. (Ich kenne C ++ 11 nicht gut genug, um zu wissen, ob dies mit intelligenten Zeigern oder mit anderen Techniken erreicht werden kann.)

Welche anderen Szenarien sind Ihrer Meinung nach für die Verwendung von Zeigern geeignet?

Würden Sie sogar empfehlen, heute über Zeiger zu lernen?

    
Gumbly jr. 06.09.2014, 22:38
quelle

6 Antworten

12

Ich kann mir Umstände vorstellen, unter denen Sie ein statisch zugewiesenes Array haben und einen rohen Zeiger verwenden möchten, um es in Hochleistungscode zu durchlaufen. Es ist immer noch nichts falsch daran.

Ihre # 1 ist wahr.

Ihre # 2 ist möglicherweise nicht richtig: Wenn Sie "Umwandlungen" verwenden, um rohe Zeiger zu konvertieren, die einer Bibliothek eines Drittanbieters gehören, in intelligente Zeiger (was lokalen Besitz bedeutet), dann ist etwas schrecklich schiefgelaufen.

Ihre # 3 ist technisch wahr, aber vermeiden Sie dies, wann immer Sie können.

Was heute nicht empfohlen wird, ist das Spielen mit rohen Zeigern zu Ihrem eigenen, dynamisch zugewiesenen Speicher . Das heißt, der Ratschlag besteht darin, new ohne Smart Pointer zu vermeiden (und die Folge ist, dass Sie delete nicht benötigen sollten).

    
Lightness Races in Orbit 06.09.2014, 22:43
quelle
8

Jeder ist gegen rohe Zeigern, da es viel zu einfach ist, sie zu verlieren.

Aber Sie können rohe Zeiger verwenden, um auf Daten zu verweisen, die sich irgendwo anders befinden ... nur nicht new / delete sie. Verwenden Sie dafür std::unique_ptr oder std::shared_ptr . Oder verwenden Sie für dumme (POD) Speicherpuffer std::vector<unsigned char> , nicht malloc und free selbst.

Stellen Sie sich ein std::vector<heavy_object*> vor, wenn Sie mit Unterauswahlen von Objekten jonglieren müssen, die nicht einfach zu kopieren sind, aber bereits an anderer Stelle existieren. Sie brauchen Zeiger dafür.

Sie brauchen auch Zeiger in Funktionen für optionale Argumente, wo Referenzen sie nicht abschneiden, da Sie nullptr übergeben können.

Zeiger auf aufeinanderfolgende Objekte können auch leicht ohne std::iterator overhead iteriert werden. Nur ++ oder -- und das war's. Ich verwende oft direkte Zeiger-Iteration anstelle von begin , end für Vektoren.

Wenn du verstehst, wie sie funktionieren ... wirst du sie sehr brauchen und sie werden sie richtig benutzen.

    
CodeAngry 06.09.2014 22:51
quelle
6

Intelligente Zeiger werden für die Behandlung von Objektbesitzproblemen verwendet, aber nicht alle Zeiger werden verwendet, um mit Objektbesitz umzugehen. Zum Beispiel ist es sinnvoller, einen rohen Zeiger an eine Funktion zu übergeben, wenn Sie nicht vorhaben, das Eigentumsrecht an diese Funktion zu übergeben (d. H. Sie möchten nur, dass die Funktion mit den vom Zeiger adressierten Daten umgeht)

    
JarkkoL 06.09.2014 22:53
quelle
3

IMHO Raw-Zeiger haben immer noch ihren Platz.

Was C ++ 11 uns gibt, ist die Fähigkeit, die Lebensdauer von rohen Zeigern zu verwalten, so dass wir sie nicht selbst löschen müssen.

Es ist nichts Falsches daran, rohe Zeiger zu verwenden, solange sie von einem intelligenten Zeiger / Zeiger-Manager im richtigen Bereich oder Rahmen verwaltet werden, um sicherzustellen, dass ihre Lebensdauer korrekt ist. Wenn das wahr ist, dann müssen Sie niemals einen rohen Zeiger löschen, und Sie können ihn sicher innerhalb des Umfangs / Rahmens verwenden, während dessen seine Lebenszeit garantiert ist.

Ich würde sagen, wenn möglich, speichern Sie einen rohen Zeiger auf Ihr neues Objekt in einem std::unique_ptr , wenn seine Lebensdauer von einem bestimmten Bereich / Rahmen gesteuert werden soll. Sobald dies geschehen ist, verwenden Sie den rohen Zeiger innerhalb dieses Bereichsrahmens. Nur nie löschen Sie es;

Manchmal ist es nicht möglich, die Lebensdauer eines neuen Objekts von einem einzelnen Bereich oder Rahmen zu verwalten. In diesem Fall verwenden Sie std::shared_ptr in jedem Bereich / Frame, der unabhängig die Lebensdauer des neuen Objekts verwalten muss. Dann gibt es innerhalb jedes Bereichs / Rahmens keinen Grund, den rohen Zeiger nicht wie bei der Verwaltung durch std::unique_ptr zu verwenden.

Es gibt also oft keinen Grund, den Geschwindigkeitsnachteilen von Smartpointern zu begegnen, da eine ihrer Stärken darin besteht, die Lebensdauer des neuen Objekts zu verwalten, um die Gültigkeit des rohen Pointers und die automatische Zerstörung seiner zu gewährleisten Objekt, wenn es nicht mehr benötigt wird.

Es gibt andere Zeiten, in denen ein roher Zeiger nicht geeignet ist.

Zum Beispiel, wenn ein verwalteter Zeiger "Besitz" auf einen anderen Bereich / Rahmen übertragen muss. In diesem Fall müssen Sie den Bereich / Rahmen ändern, der für die Lebensdauer des neuen Objekts verantwortlich ist. In diesen Fällen vermeiden rohe Zeiger wie die Pest!

    
Galik 07.09.2014 00:09
quelle
1
  

Welche anderen Szenarien sind Ihrer Meinung nach für die Verwendung von Zeigern geeignet?

Eines der Hauptszenarios, in denen rohe Zeiger verwendet werden, ist, wenn Sie nicht besitzende -Zeiger haben. In der Regel, wenn eine Referenz funktionieren würde, Sie aber die Einschränkungen einer Referenz vermeiden möchten (nicht umsetzbar, nicht kopierbar). Sie könnten in diesen Fällen einen reference_wrapper -Typ verwenden, aber es ist einfacher, stattdessen einen rohen Zeiger zu verwenden. Smart-Pointer codieren den Besitz (wer das Objekt erstellt und zerstört), wenn also kein Besitz zu verschlüsseln ist (weil es sonst impliziert ist), dann ist ein roher Pointer OK.

Um es klar zu stellen, typische Beispiele für das, was ich gerade erklärt habe, sind Dinge wie:

  • temporäre kopierbare Funktoren, die einen Zeiger auf ein Objekt benötigen, das sie nicht besitzen.
  • interne Querverweise innerhalb einer Datenstruktur (z. B. "back pointer").

Aber es ist wichtig zu beachten, dass diese Dinge im Allgemeinen nicht in Schnittstellen vorhanden sein sollten. Im Allgemeinen können Sie rohe Zeiger in Schnittstellen (z. B. Bibliotheksfunktionen und -klassen) ziemlich vollständig vermeiden und sie nur intern, d. H. Im bibliotheksseitigen Code und nicht im benutzerseitigen Code, verwenden. Mit anderen Worten, wenn Sie rohe Zeiger verwenden müssen, verstecken Sie sie weg.

Manchmal werden auch rohe Zeiger für optionale Funktionsparameter angezeigt, in denen Sie nullptr übergeben können, wenn Sie dieses Ergebnis nicht möchten.

Die Hauptsache, die vermieden werden sollte, und im Allgemeinen vermieden werden kann, ist, dass nackte new / delete den Benutzercode aufruft. Eine typische gute moderne C ++ - Bibliothek (und noch mehr mit C ++ 11) wird keine solchen nackten new / delete -Erscheinungen haben, und das ist eine Tatsache.

Raw-Zeiger sind nicht so sehr ein Problem für sich, was problematisch ist, ist (1) manuelle Speicherverwaltung und (2) Eigentumsverwaltung (was problematisch ist, wenn rohe Zeiger anstelle von intelligenten Zeigern verwendet werden).

  

Würden Sie sogar empfehlen, heute über Zeiger zu lernen?

Natürlich sollten Sie über Zeiger lernen. Sie sind essentiell für das Verständnis der Programmierung und für das Schreiben von bibliotheksseitigem Code. Raw Pointer sind immer noch in den Eingeweiden einer Menge von Bibliothekscode und dergleichen vorhanden, auch wenn Sie sie nicht sehen.

    
Mikael Persson 06.09.2014 23:02
quelle
-1

häufige Gründe, rohe Hinweise von meinem Kopf zu verwenden.

  1. Binärdateien lesen und analysieren
  2. Interaktion direkt mit der Hardware
  3. Arrays?
  4. Geschwindigkeit. AFAIK Smart Zeiger sind langsamer als rohe Zeiger und es gibt relativ sichere Möglichkeiten, rohe Zeiger zu verwenden. Siehe zum Beispiel die Code-Basis von Chromium oder WebKit's. Beide verwenden verschiedene Arten von nachverfolgbarem Speicher ohne den vollen Aufwand von intelligenten Zeigern. Natürlich auch mit Einschränkungen.
gman 06.09.2014 22:54
quelle

Tags und Links