Ich versuche, Inheritance und Deep Copy in den Griff zu bekommen, aber ich habe einige Probleme. Ich habe 3 Klassen (1 Basis und 2 Abgeleitet) wie folgt:

class Base {
protected:
    int id;
public:
    Base(int i) : id(i) {};
    virtual ~Base();
};

class DeriveA : public Base {
    int specialID;
public:
    DeriveA(int s, int i) : Base(i), specialID(s) {};
    ~DeriveA();
};

class DeriveB : public Base {
    int specialID;
public:
    DeriveB(int s, int i) : Base(i), specialID(s) {};
    ~DeriveB();
};

Auf meiner Hauptsache habe ich so etwas:

int main() {

    Base **Array;
    int i, n;
    Array = new Base*[5];
    for (i = 0 ; i < 5 ; i++) {
        n = rand() % 2;
        if (n)
            Array[i] = new DeriveA(i, n);
        else
            Array[i] = new DeriveB(i, n);
    }
}

Wenn bestimmte Umstände erfüllt sind, möchte ich ein Array-Objekt über andere Objekte kopieren. Es fällt mir schwer, einen Kopierkonstruktor dafür zu erstellen, da Array[0] = Array[2]; bei mir nicht funktioniert. Ich möchte keine Vektoren oder std :: copy verwenden, da dies nicht mein "pädagogisches" Ziel ist.

PS 1: Ist der Zuweisungsoperator für diesen Zweck besser, da ich alle Objekte des Arrays initialisiert habe?

PS 2: Da es sich um einen generischen Code handelt, habe ich einige Fehler ausgelassen. Bitte ignorieren Sie sie und konzentrieren Sie sich auf die Frage.

2
Alex R. 4 Jän. 2016 im 18:41

2 Antworten

Beste Antwort

Wenn Sie die Objekte klonen möchten, anstatt Zeiger auf dasselbe Objekt zu kopieren, können Sie eine virtuelle Klonfunktion verwenden:

class Base {
public:
    virtual Base* clone() const = 0;
    virtual ~Base();  // Don't forget 'virtual' here
};

class DeriveA : public Base {
public:
    virtual Base* clone() const { return new DeriveA(*this); }
};

class DeriveB : public Base {
public:
    virtual Base* clone() const { return new DeriveB(*this); }
};


// ...

Array[0] = Array[2]->clone();
2
molbdnilo 4 Jän. 2016 im 16:41

Zunächst sollten Sie ein Array von Base* zugewiesen haben:

Array = new Base*[5];

Und so initialisieren Sie die Elementzeiger:

Array[i] = new DeriveA(i,n);

So nicht:

// * added for further clarification, otherwise invalid and rejected at compilation
*Array[i] = DeriveA(i,n);

Denn das ist:

  1. Dereferenzierung eines nicht initialisierten Zeigers (undefiniertes Verhalten)
  2. Objekt schneiden

Beachten Sie, dass in Ihrem Base ein virtual Destruktor fehlt.

Und dann natürlich die Freigabe ... Sie können herausfinden, wie es geht hier.

3
Community 23 Mai 2017 im 11:52