in C ++, was ist der Unterschied zwischen einem Objekt und einem Zeiger auf ein Objekt?

7

In java und objective-c ist eine Variable, die ein Objekt repräsentiert, im Allgemeinen ein Zeiger auf dieses Objekt. Es scheint jedoch, dass es in C ++ üblich ist, dass Nicht-Zeigertypen Objekte enthalten. Was ist der Unterschied zwischen den beiden?

Wenn ich eine Struktur als Argument an eine Funktion übergebe, glaube ich, dass ich Wert übergebe, was bedeutet, dass ich tatsächlich eine neue Struktur im Speicher erstelle und Änderungen an dieser Struktur innerhalb der Funktion, an die sie übergeben wird, nicht Auswirkungen auf die "source" -Struktur außerhalb der Funktion. Wenn ich jedoch einen Zeiger auf eine Struktur übergebe, gibt es immer noch nur eine Originalstruktur, und Änderungen an der Struktur, auf die der Zeiger verweist, sind für jeden Code sichtbar, der diese Struktur kennt. Habe ich das richtig?

Also, gibt es einen Unterschied zu Objekten? Wenn ich ein Objekt ohne Zeiger an eine Funktion übergebe, wird das gesamte Objekt kopiert?

    
morgancodes 21.03.2011, 00:38
quelle

6 Antworten

15

Es ist genau wie du gesagt hast.

Wenn Sie ein Objekt nach Wert übergeben, wird sein Kopierkonstruktor aufgerufen, um eine neue Instanz eines solchen Objekts zu erzeugen, das innerhalb der Funktion verwendet wird. Die Änderungen, die an einem solchen neuen Objekt vorgenommen werden, werden nicht in das ursprüngliche Objekt 1 übernommen.

Wie bei Strukturen erstellt der Standardkopiekonstruktor nur eine flache Kopie des ursprünglichen Objekts - d. h. seine Felder werden in die neue Instanz kopiert 2 ; in vielen Fällen ist dies nicht wünschenswert (z. B. wenn das Objekt einen Zeiger / eine andere Ressource umschließt), so dass es Klassen gibt, die den Kopierkonstruktor neu definieren oder vollständig deaktivieren. Objekte dieser letzten Klassen können nur per Zeiger oder Verweis übergeben werden.

Das Übergeben von Objekten nach Wert kann teuer sein, wenn sie größer sind als ein Zeiger (in der Größe) oder im Allgemeinen, wenn ihr Kopierkonstruktor nicht "billig" ist. Auf der anderen Seite, im Vergleich zu Zeigern, ergibt der Vorübergehender-Wert die üblichen Vorteile, dass der Besitzer des Zeigers nicht spezifiziert werden muss, der Angerufene das tun muss, was er mit dem Objekt wünscht, usw.

Beachten Sie, dass das Übergeben eines Objekts nach Wert den Polymorphismus beendet. Dies liegt daran, dass eine Funktion, die ein Objekt per Wert erhält, ein statisch typisiertes Objekt mit einer genauen Größe und einem genauen Typ erhält. Jeder Versuch, ein Objekt einer abgeleiteten Klasse zu übergeben, führt zu einem Objekt-Slicing (der Kopierkonstruktor für die Basisklasse wird also aufgerufen) kopiert standardmäßig die Felder, die in der Basisklasse verfügbar sind.)

Dies ist der Grund, warum oft die bevorzugte Methode zum Übergeben von Objekten in const reference ist. Dies bringt mehrere Vorteile:

  • keine Kopien beteiligt; Das Objekt, das der Angerufene sehen wird, ist genau das, das zum Zeitpunkt des Anrufs angegeben wurde;
  • Mit dem const Qualifier;
  • können keine Änderungen am ursprünglichen Objekt vorgenommen werden
  • Wenn der Angerufene jedoch eine Kopie des Objekts ändern muss, kann er dennoch selbst eine Kopie aus der Referenz erstellen;
  • keine umständliche Zeigersyntax;
  • Polymorphismus beibehalten, da wir hinter den Kulissen tatsächlich einen Zeiger übergeben;
  • keine großen Zweifel am Objektbesitz: Die allgemeine Regel über Referenzen ist, dass sie dem Aufrufer gehören.
  1. Soweit die "rohen Felder" des Objekts betroffen sind; Natürlich, wenn das ursprüngliche Objekt und die Kopie weiterhin einen Zeiger / Handle für die gleiche Ressource teilen, können einige Änderungen an der einen die andere beeinflussen.

  2. Primitive Typen (und im Allgemeinen PODs) werden bitweise kopiert, während der Kopierkonstruktor für Nicht-POD-Typen aufgerufen wird.

Matteo Italia 21.03.2011, 00:49
quelle
3

Der Unterschied liegt meistens darin, wo im Speicher ein Objekt zugewiesen ist. Zum Beispiel:

%Vor%     
aroth 21.03.2011 00:56
quelle
1

In C ++ ist eine Variable die Variable, die sie darstellt. Es ist das tatsächliche Objekt im Speicher, an der tatsächlichen Position.

Sie können jedoch wählen, dass eine solche Variable stattdessen einen Zeiger darstellt. In diesem Fall sagt sie: "Hey, ich bin ich, ich deute auf drüben! Das Objekt, das Sie haben wollen, ist nicht da, es ist DORT Ja, da! Geh schon, komm hin! ".

Wenn Sie nicht ausdrücklich den "Referenztyp" von C ++ verwenden, was ich nicht befürchte, dann sind ALLE Argumente, die Sie übergeben, wertmäßig.

    
Arafangion 21.03.2011 00:46
quelle
0

Die Antworten auf die Fragen im zweiten und dritten Absatz sind beide "Ja". Genauer gesagt, wenn Sie ein Objekt als Wert an eine Funktion übergeben, erhält die Funktion eine Kopie dieses Objekts (erstellt vom Kopierkonstruktor).

    
Jon 21.03.2011 00:42
quelle
0

Wenn Sie ein Objekt als Wert an eine Funktion übergeben, wird es mithilfe des Kopierkonstruktors der Klasse kopiert. Wenn Sie keinen Kopierkonstruktor definiert haben, wird ein Standard vom Compiler angegeben (es sei denn, Sie unternehmen spezielle Maßnahmen, um dies zu vermeiden), was dem Kopieren der Elemente von Hand entspricht.

Am liebsten übermittelst du lieber eine const-Referenz als einen Zeiger oder das Objekt selbst.

(Vielleicht möchten Sie wissen, dass ein struct nur ein class ist, dessen Mitglieder standardmäßig public sind; insbesondere können Strukturen auch benutzerdefinierte Kopierkonstruktoren haben. Eine Struktur ist nicht notwendigerweise einfach einfache inerte Daten.)

    
Gareth McCaughan 21.03.2011 00:44
quelle
0

Sie haben das richtig.

Tatsächlich funktioniert das so. Ein Zeiger speichert die Speicheradresse einer Variablen.

Wenn Sie einen Zeiger (an ein Objekt) für eine Funktion als Parameter übergeben, bedeutet dies, dass die Funktion über die Speicheradresse auf dieses Objekt zugreifen kann, anstatt dass ein neues Objekt auf dem Stapel erstellt wird.

Überprüfen Sie Dieser Thread für weitere Informationen über Zeiger.

    
karlphillip 21.03.2011 00:46
quelle

Tags und Links