Also habe ich eine Basisklasse bekam die wie folgt aussieht:Gibt es eine Möglichkeit, Speicherlecks in einer abgeleiteten Klasse zu verhindern, ohne die Basisklasse zu ändern?
class base {
public:
base() {
std::cout << "We created a base!" << std::endl;
}
~base() {
std::cout << "We destroyed a base!" << std::endl;
}
};
Und ich habe eine abgeleitete Klasse, die wie folgt aussieht:
class leaks_memory : public base {
public:
leaks_memory(size_t count) :
memory(new int[count]), size_of_memory(count)
{
announce();
}
leaks_memory(const leaks_memory & lm) :
leaks_memory(lm.size_of_memory)
{
std::copy(lm.memory, lm.memory + size_of_memory, memory);
}
void swap(leaks_memory & lm) noexcept {
std::swap(lm.memory, memory);
std::swap(lm.size_of_memory, size_of_memory);
}
leaks_memory(leaks_memory && lm) {
swap(lm);
}
leaks_memory & operator=(leaks_memory lm) {
swap(lm);
return *this;
}
~leaks_memory() {
delete[] memory;
dennounce();
}
int & operator[](size_t index) {
return memory[index];
}
const int & operator[](size_t index) const {
return memory[index];
}
private:
int * memory;
size_t size_of_memory;
void announce() const noexcept {
std::cout << "We created a Leaks Memory!" << std::endl;
}
void dennounce() const noexcept {
std::cout << "We destroyed a Leaks Memory!" << std::endl;
}
};
Nun sind diese nicht, auf ihre eigenen Fragen, bis ich Code schreiben, der wie folgt aussieht:
int main() {
std::unique_ptr<base> base_ptr;
std::atomic_bool done = false;
std::thread input_thread{ [&done] {
std::getline(std::cin, std::string());
done = true;
} };
while (!done) {
base_ptr = std::make_unique<leaks_memory>(20'000);
}
input_thread.join();
return 0;
}
Dieser Code Lecks jede Iteration der Schleife 20KB, weil die leaks_memory
destructor nie aufgerufen wird!
Nun, natürlich, ich könnte dieses Problem beheben, indem bearbeitet zu base
machen:
virtual ~base() {
std::cout << "We destroyed a base!" << std::endl;
}
Und in der Tat, wenn ich den gleichen Code nach dieser Änderung laufen, ich habe nicht mehr dieses Speicherleck.
Aber was ist, wenn ich in einer Situation bin, in der ich die Klasse base
nicht bearbeiten kann? Gibt es eine Möglichkeit, den Speicherverlust zu verhindern, ohne das Design des ausführenden Codes vollständig zu ändern?
Haben Sie einen 'virtuellen' Destruktor in der Basisklasse. –
@ πάνταῥεῖ Bitte lesen Sie die gesamte Eingabeaufforderung. Ich möchte wissen, ob es möglich ist * ohne * die Basisklasse zu modifizieren. Ich weiß bereits, dass es einen Fehler machen wird, den Destruktor virtuell zu machen. – Xirema
@ πάνταῥεῖ BTW-Destruktoren sollten immer virtuell sein. –