Ich verwende eine abgeleitete Klasse und einen Vektor von Zeigern auf Objekte aus dieser Klasse. Ich habe einige Probleme mit der Implementierung von Kopierkonstruktoren usw., auch nachdem ich viel darüber gelesen habe. Ich benutze C++ 11.Vektor von Objektzeigern und Objekten, die den Gültigkeitsbereich verlassen
Ich habe eine Schleife, wo neue Objekte der abgeleiteten Klasse erstellt werden, und ich möchte dann diese in den Vektor setzen. Da es sich jedoch um einen Vektor von Zeigern handelt, muss ich stattdessen die Adresse des erstellten Objekts angeben.
Ich glaube, dass meine Probleme von dieser Tatsache herrühren, zusammen mit Objekten, die außerhalb des Geltungsbereichs liegen und ich nicht in der Lage bin, Kopierkonstruktoren/Kopierzuweisungskonstruktoren usw. in zufriedenstellender Weise zu implementieren.
Ich habe ein minimales Beispiel gemacht, das meiner Meinung nach mein Problem veranschaulicht. Lassen Sie uns die Ersteinrichtung sagen ist wie folgt (ich weiß es nicht viel Sinn macht, zum Beispiel mit dem Zeiger *n
, aber ich denke, das die Probleme mit meinem eigentlichen Code zeigt):
using namespace std;
#include <iostream>
#include <vector>
class Base {
protected:
int* n;
public:
void display(string name="") {cout << name << "n = " << *n << endl;}
Base() {}
Base(int n_) {
*n=n_;
cout << "Initialised to " << *n << endl;
}
};
class Derived : public Base {
public:
Derived() : Base() {}
Derived(int n_) : Base(n_) {}
};
int main(int argc, const char* argv[]) {
vector<Base*> list;
for(int i=0;i<5;i++) {
Derived tmp(i);
tmp.display("Tmp: ");
list.push_back(&tmp);
}
cout << endl;
for(int i=0;i<list.size();i++) {
cout << "Address of " << i << ": " << list[i] << endl;
list[i]->display("Element "+to_string(i)+" : ");
}
}
Der Ausgang dieses ist :
Initialised to 0
Tmp: n = 0
Initialised to 1
Tmp: n = 1
Initialised to 2
Tmp: n = 2
Initialised to 3
Tmp: n = 3
Initialised to 4
Tmp: n = 4
Address of 0: 0x7fff3a1df2d0
Element 0 : n = 0
Address of 1: 0x7fff3a1df2d0
Element 1 : n = 0
Address of 2: 0x7fff3a1df2d0
Element 2 : n = 0
Address of 3: 0x7fff3a1df2d0
Element 3 : n = 0
Address of 4: 0x7fff3a1df2d0
Element 4 : n = 0
So nach der Schleife alle Elemente in der Liste auf die gleiche Adresse, wobei n = 0 (wahrscheinlich nicht definiertes Verhalten von tmp
außerhalb des Gültigkeitsbereichs gehen).
So und nicht nur die Adresse tmp
in list
Putting Ich denke, ich muss irgendwie Instanzen Derived
machen, die die Schleife überleben, während immer noch nur Adressen in list
haben.
Wie erwähnt habe ich versucht, dies mit verschiedenen speziellen Member-Funktionen ohne Glück zu tun.
Beachten Sie, dass die Implementierung eines Vektors der Objekte möglicherweise einfacher zu sein scheint, aber das führt zu anderen Problemen in meinem tatsächlichen Code. Wenn ich das nicht funktioniere, werde ich es stattdessen versuchen.
Die Dereferenzierung eines nicht initialisierten Zeigers ist ein undefiniertes Verhalten: Sie müssen etwas Speicher zuweisen, damit 'n' auf den Punkt zeigt, bevor Sie' * n = n_' in 'B's Konstruktor ausführen. Für 'list.push_back' (&tmp); 'haben Sie tatsächlich (automatischen) Speicher zugewiesen, aber wie Sie anhand des Werts der Zeiger sehen können, ist der Speicher immer derselbe: Er wird wiederverwendet, da der Bereich von' tmp' nur auf den Ende der Schleife – BeyelerStudios
Was ist der Zweck von 'Base :: n'? Warum ist es ein Zeiger? –
@BeyelerStudios: Meinst du, wie z. B. 'n = 0' vor' * n = n_' hinzufügen? @Joachim Pileborg: Wie im OP erwähnt, weiß ich, dass dies keinen Sinn ergibt, es ist eine sehr einfache Beispielversion eines großen Programms – jorgen