Ich bin wirklich auf dieses Problem fest. Ich habe eine Anwendung mit einem Speicherleck. Um das Problem loszuwerden, muss ich Destruktoren für Klassen aufrufen.Aufruf von 3 Destruktor-Schichten in Polymorphie
für 2 Schichten von Klassen, dieses Problem ist trivial, aber in dieser Situation gibt es drei Schichten von Klassen und ich kann keinen Weg finden, um diese zu kompilieren zu erhalten:
#include<iostream>
using namespace std;
/* *MUST* be an abstract class and contains data that must be freed */
class C {
public:
virtual ~C()=0;
};
/* Contains concrete methods and contains data that has to be freed */
class B:public C {
public:
virtual ~B();
};
/* contains no data, only methods nothing needs to be freed in here */
class A:public B {
public:
~A();
};
int main(){
C *c = new A;
return 0;
}
Wenn ich den Code, den ich kompilieren erhalten Sie den Fehler:
[email protected] ~ $ gcc deleteme.cpp -std=c++11
/tmp/cc7nxaw5.o: In function `main':
deleteme.cpp:(.text+0x12): undefined reference to `operator new(unsigned int)'
/tmp/cc7nxaw5.o: In function `__static_initialization_and_destruction_0(int, int)':
deleteme.cpp:(.text+0x4b): undefined reference to `std::ios_base::Init::Init()'
deleteme.cpp:(.text+0x62): undefined reference to `std::ios_base::Init::~Init()'
/tmp/cc7nxaw5.o: In function `B::B()':
deleteme.cpp:(.text._ZN1BC2Ev[_ZN1BC5Ev]+0x16): undefined reference to `vtable for B'
/tmp/cc7nxaw5.o: In function `A::A()':
deleteme.cpp:(.text._ZN1AC2Ev[_ZN1AC5Ev]+0x16): undefined reference to `vtable for A'
/tmp/cc7nxaw5.o:(.rodata._ZTV1C[_ZTV1C]+0x8): undefined reference to `__cxa_pure_virtual'
/tmp/cc7nxaw5.o:(.rodata._ZTV1C[_ZTV1C]+0xc): undefined reference to `__cxa_pure_virtual'
/tmp/cc7nxaw5.o:(.rodata._ZTI1C[_ZTI1C]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
collect2: error: ld returned 1 exit status
jemand eine Möglichkeit, herauszufinden, kann, dass ich die Destruktoren umschreiben kann, so dass Destruktoren für A, B und C sind alle aufgerufen?
Ich reiße meine Haare mit diesem, jede Hilfe würde geschätzt werden. Ich kann jedoch nicht die Anforderungen in Kommentaren oder der Vererbungshierarchie ändern, um dies zu tun, würde ich die gesamte Anwendung neu schreiben müssen.
Sehr geschätzt.
Edit: so vielen Dank für die Kommentare unten auf die Frage, die Lösung, die funktioniert für mich ist:
#include<iostream>
using namespace std;
/* *MUST* be an abstract class and contains data that must be freed */
class C {
public:
virtual ~C()=0;
};
C::~C(){
cout<<"destroying C"<<endl;
}
/* Contains concrete methods and contains data that have to be freed */
class B:public C {
public:
~B();
};
B::~B(){
cout<<"destroying B"<<endl;
}
/* contains no data, only methods nothing needs to be freed in here */
class A:public B {
public:
~A();
};
A::~A(){
cout<<"destroying A"<<endl;
}
int main(){
C *c = new A;
delete c;
return 0;
}
Vielen Dank für Ihre Ratschläge sehr.
Geben Sie Ihre Destruktoren Definition und vielleicht wird es besser funktionieren. '~ B() {}' –
Auch das Hinzufügen von 'delete c;' wird sie tatsächlich aufrufen. Oder besser: Verwenden Sie intelligente Zeiger. –
Das hat mich verwirrt: '/ * * MUSS * eine abstrakte Klasse sein und enthält Daten, die befreit werden müssen * /' und 'virtual ~ C() = 0;'. 'C' hat Daten zu befreien. Nur "C" sollte genug über "C" wissen, um dies zu können. 'C' sollte einen Destruktor haben. Klärung. Sie können einen reinen virtuellen Destruktor haben und trotzdem einen Destruktor bereitstellen. Seltsam, aber wahr. – user4581301