Verhalten Abstrakter und abgeleiteter Klassen
-
Hallo,
ich arbeite an einem Projekt, bei dem ich u.a. eine Graphsuche auf Bilddaten durchführe.
Ich habe mir eine abstrakte Klasse, sagen wir A, definiert, die mir eine bestimmte Schnittstelle zur Verfügung stellt. Von dieser Klasse habe ich mir dann eine Unterklasse B abgeleitet, die den Bilddatensatz hält und zwar in einer anderen Klasse C (diese kapselt diesen Datensatz). Ein Objekt von Klasse C wird bei der Erzeugung eines Objekts von B erzeugt.
Das Objekt der Klasse B führt bestimmte Berechnungen in meinem Algorithmus auf dem Bilddatensatz auf.
Der Algorithmus lief bisher. Ich hatte allerdings versäumt, in Klasse A einen virtuellen Destruktor bereit zu stellen.
Nach der Definition dieses Destruktors wird allerdings irgendwie in den Speicherbereich geschrieben, in dem die Bilddaten vorliegen.
Nochmal konkret:class A
{
public:virtual ~A()
{
}
virtual double calculate(point2D point) const = 0;
};class B : public A
{private:
C object;public:
B(...);
virtual ~B();
}C wird im Konstruktor von B erzeugt und hält Daten, wie folgt:
Ausgabe der Daten von C nach Ausführung des Alg. ohne virtuelle Definition des Destruktors in A:
240 240 240 240 240 240 240 240 240 240 240 240
240 1 1 1 1 1 1 1 1 1 1 240
240 1 1 1 1 1 1 1 1 1 1 240
1 1 1 1 1 1 1 1 1 1 1 240
1 1 1 1 1 1 1 1 1 1 1 240
1 1 1 1 1 1 1 1 1 1 1 240
1 1 1 1 1 1 1 1 1 1 1 240
1 1 1 1 1 1 1 1 1 1 1 240
1 1 1 1 1 1 1 1 1 1 1 240
1 240 240 240 240 240 240 240 240 240 240 240Ausgabe der Daten von C nach Ausführung des Alg. MIT virtueller Definition des Destruktors in A:
4336 2053 368 2053 328 2053 4416 2053 2 0 0 0
0 0 0 -8 48 0 41 0 4336 2053 288 2053
368 2053 4656 2053 1 0 0 0 0 0 0 -8
36 0 41 0 4336 2053 328 2053 288 2053 0 0
0 0 0 0 0 0 0 -8 5 0 41 0
4416 2053 408 2053 408 2053 0 0 0 0 0 0
0 0 0 -8 54 0 41 0 288 2053 4416 2053
4416 2053 0 0 0 0 0 0 0 0 0 -8
17 0 49 0 0 0 488 2053 488 2053 328 2053
2 0 1 0 0 0 0 -8 27 0 240 240Ich programmiere noch nicht so lange in C++ und habe keine Erklärung. Hat jemand irgendeine Idee?
-
Hattest Du B über einen Basiszeiger von A zuvor gelöscht ?
B b = new B; A * a = &b; delete a;
Wenn ja, was macht der Destruktor von B ?
-
nein habe ich nicht. B wird nicht im Freispeicher angelegt. Ich mache folgendes:
zur Verfolständigung: Ein Objekt vom Typ D ist für die Graphsuche verantwortlich. Diesem Objekt übergebe ich bei der Erzeugung eine Referenz auf B. D kann dann calculate von B aufrufen. Auf einem Objekt einer weiteren Klasse E (sorry..!) wird dann der eigentliche Algorithmus aufgerufen:
main()
{
short* pData = new short[...];
...
B b(pData, ...);
const B& rB = b;
D d(rB,...);
const D& rD = d;
E e(rD,...);
e.startAlgo();
... (nur Debugging-ausgaben)
delete[] pData;
}startAlgo() ruft über den Zeiger auf d den eigentlichen Algorithmus auf. d führt dann Berechnungen mittels Zeiger auf b durch.
Im Konstruktor von B wird automatisch der Konstruktor von C aufgerufen (Halten der Bilddaten).
Im Konstruktor von C wird per Memcopy das Array neu angelegt und die Werte kopiert.
Im Destruktor von C gebe ich schön den Speicher wieder frei.
Der Destruktor von B macht nix, er sollte automatisch den von C aufrufen.
-
Was erwartet der Konstruktor von D ?
-
ich habe jetzt den Effekt lokalisiert. Bei Neukompilation aller Files und linken aller neu erstellten Object-Files tritt der Effekt nicht mehr auf.
Der Effekt, Fehler, keine Ahnung tritt immer dann auf, wenn ich mittels meines MakeFiles Klasse B (A liegt nur als Header vor) neu compiliere und zu den ALTEN Objektfiles dazu linke.
Keine Ahnung. Scheint wohl so zu sein, daß irgendeine Typinformation verloren geht. Vielleicht weiß da jemand was.