5 Stimmen

Dynamisches Array... Kopierkonstruktor, Destruktor, überladener Zuweisungsoperator

Ich lerne gerade für meine Zwischenprüfung. Es wird eine Frage über das dynamische Einrichten eines Arrays geben, und vielleicht über einen Kopierkonstruktor, einen Destruktor und das Überladen des Zuweisungsoperators. Können Sie bitte überprüfen, ob ich richtig liege. Außerdem verstehe ich nicht, was Überladen des Zuweisungsoperators bedeutet. Können Sie mir hier weiterhelfen?

class A
{
int* myArray;   //basically I created a pointer called myArray, 
A()             //are my copy constructors correct? A(), and A(int size)?
{
    myArray = 0;
}
A(int size)
{
    myArray = new int[size];
}
~A()             // I think my destructor is correct
{
    delete [] myArray;
}

Können Sie bitte meinen Code überprüfen? Auch wie kann ich Zuweisung Operator überladen?

Vielen Dank im Voraus.

8voto

okutane Punkte 13127

Der Kopierkonstruktor wird für die Erstellung eines Objekts auf der Grundlage einer anderen Instanz desselben Typs verwendet. Sie haben keinen solchen. Sie können ihn mit Code wie diesem definieren:

A(const A &other)
{
   myArray = new int[other._size];
   _size = other._size;
   memcpy(myArray, other.myArray, sizeof(int) * _size);
}

Sie sollten Ihre Klasse ändern, so dass es _size von Array zu speichern, müssen Sie auch Sichtbarkeit Ihrer Konstruktoren und Destruktor zu öffentlich ändern.

Der überladene Zuweisungsoperator sollte wie folgt aussehen:

const A &operator=(const A &other)
{
   if(this == &other) return *this; // handling of self assignment, thanks for your advice, arul.
   delete[] myArray; // freeing previously used memory
   myArray = new int[other._size];
   _size = other._size;
   memcpy(myArray, other.myArray, sizeof(int) * _size);
   return *this;
}

Sie können auch eine Überprüfung der Gleichheit der Array-Größen in diesem Zuweisungsoperator hinzufügen, so dass Sie Ihr dynamisches Array ohne unnötige Neuzuweisungen von Speicher wiederverwenden können.

7voto

Sie haben korrekt 2 überladene Konstruktoren und einen Destruktor definiert.

Sie haben jedoch keine Definition einer expliziter Kopierkonstruktor richtig.

Normalerweise generiert der Compiler einen solchen für Sie, und dieser wird als impliziter Kopierkonstruktor .

Das Problem mit dem automatisch erzeugten impliziten Kopierkonstruktor in Ihrem speziellen Fall ist, dass er nur eine oberflächliche Kopie von meinArray , wo er denselben Zeigerwert verwendet, aber keinen eigenen Speicherbereich für myArray zugewiesen hat.

Das heißt, wenn Sie myArray im Originalobjekt löschen, wirkt sich das auf die Kopie aus, was wahrscheinlich nicht das ist, was Sie wollen.

Die Definition eines expliziten Kopierkonstruktors wie dieser ist hilfreich:

A(const A& copy)
  : _size(copy.size), myArray(new int[copy.size]) 
{
    // #include <algorithm> for std::copy
    std::copy(copy.data, copy.data + copy.size, data);
}

(Quelle: Kopiert aus Wikipedia )

Wenn Sie den Kopierkonstruktor auf diese Weise definieren, sollten Sie den Zuweisungsoperator nicht überladen müssen. Wenn Sie ein neues Objekt erstellen und es dem ersten Objekt zuweisen, das Sie erstellt haben, erstellen Sie erfolgreich eine unabhängige Kopie des ersten Objekts.

Edit : Von 本品 :

Der Kopierzuweisungsoperator unterscheidet sich vom Kopierkonstruktor dadurch, dass er die Datenelemente des Zuweisungsziels aufräumen muss (und korrekt mit der Selbstzuweisung umgehen), während der Kopierkonstruktor Werte zuweist nicht initialisierten Datenelementen Werte zuweist.

4voto

thrantir Punkte 353

Beim Umgang mit Objektkopien und dynamischer Speicherzuweisung ist es eine gute Idee, eine Swap-Hilfsfunktion zu verwenden

A(const A& other)
    : myArray(0)
    , _size(0)
{
   if(this != &other) {
      A my_tmp_a(other._size);
      std::copy(&other[0], &other[other._size], &my_tmp_a[0]);
      swap(my_tmp_a);
   }
}

const A& operator=(const A& other)
{
   if(this == &other) return *this;
   A my_tmp_a(other._size);
   std::copy(&other[0], &other[other._size], &my_tmp_a[0]); 
   swap(my_tmp_a);       
   return *this;
}

void swap(const A& other) {
   int* my_tmp_array = this.myArray;
   this.myArray = other.myArray;
   other.myArray = my_tmp_array;
   int my_tmp_size = this._size;
   this._size = other._size;
   other._size = my_tmp_size;
}

1voto

Bitte stellen Sie sicher, dass Sie drei Funktionen definieren, wenn Sie eine davon definieren wollen. Das nennt man die Alles-oder-nichts-Regel Diese sind: 1) Kopierkonstruktor. 2) Zuweisungsoperator. 3) Destruktor.

0voto

David Z Punkte 121773

Teilantwort: Das Überladen einer Funktion beinhaltet die Erstellung verschiedener Versionen dieser Funktion, die eine unterschiedliche Anzahl oder Art von Argumenten akzeptieren. Das Überladen des Zuweisungsoperators würde also bedeuten, mehrere Funktionen für den Zuweisungsoperator zu erstellen, die es ermöglichen, einer Variablen des Typs Objekte verschiedener Typen zuzuweisen. A .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X