2016-04-15 12 views
0

Konnte mir jemand den Grund erklären, warum in diesem Code MyClass (const MyClass & src) { m_X = src . m_X; } definiert ist? Ohne diese Codezeile funktioniert es auch gut und gibt die gleiche Ausgabe, die in diesem Fall 32 ist. Was ist der Unterschied zwischen dem Einsteigen und nicht? Ich habe gelesen, dass der Kopierkonstruktor automatisch erstellt wird, aber wenn Sie den Zeiger in der Klasse definiert haben, sollten Sie ihn definieren, aber ich bekomme in diesem Fall nicht den Grund.Kopieren Konstruktor Verwirrung

-Code unten:

#include <iostream> 
using namespace std; 

class MyClass 
{ 
public: 
    MyClass (int x) : m_X (new int (x)) {} 
    MyClass (const MyClass &src) 
    { 
     m_X = src.m_X; 
    } 

    void print (void) const 
    { 
     cout << *m_X; 
    } 

private: 
    int * m_X; 
}; 


int main (void) 
{ 
    MyClass a (32), c = a; 
    c.print(); 

    return 0; 
} 

Antwort

1

Der Grund, warum Sie die gleiche Ausgabe zu erhalten ist, dass Sie eine flache Kopie tun, wie der Compiler tun würde. Es ist nicht genug, nur einen Zeiger zu kopieren. Sie müssen einen neuen Zeiger erstellen und dann seinen Wert als Kopie dessen festlegen, von dem Sie kopieren. Ein korrekter Konstruktor würde wie folgt aussehen:

Jetzt hat die Kopie ihren eigenen unabhängigen Zeiger, der den gleichen Wert hat.

Beachten Sie auch, dass Sie einen Destruktor benötigen, um den Speicher und einen richtigen Kopierzuweisungsoperator zu löschen, da der Standardkopiezuweisungsoperator dasselbe wie der Standardkopiekonstruktor ausführt.

2

Der standardmäßige Kopierkonstruktor sowie Ihr Kopierkonstruktor führt eine stichhaltige Kopie (oder oberflächliche Kopie) aus. In diesem Fall haben Sie einen Zeiger, dessen Wert die Adresse ist, an der sich die Daten befinden. Diese Adresse, was kopiert wird.

Wie in anderen Beiträgen erwähnt, müssen Sie Zeiger ein wenig besser verwalten.

2

Das Problem mit dem Compiler, der einen (und Ihren) erzeugt, ist, dass er den Zeiger kopiert. Sie haben nun zwei Zeiger c.m_x und a.m_x, die beide auf das gleiche zugewiesene Heap-Objekt zeigen. Wem gehört es? Was passiert, wenn Sie ein löschen, sollte es den Speicher löschen, den es zugewiesen hat (Sie tun dies nicht tun), aber c ist immer noch dabei.

Aus diesem Grund gibt es std::shared_ptr. Es ist für diesen Fall entwickelt, es hat die Right Thing By Magic

int * m_X Ersetzen von std::shared_ptr<int> m_X

Verwandte Themen