Kursinhalt
C++ Smart Pointers
C++ Smart Pointers
Bereitstellung Benutzerdefinierter Löschfunktionen für Smart-Pointer
Wir wissen bereits, dass Smart-Pointer automatisch die Destruktoren der dynamischen Objekte aufrufen können, wenn die Objekte nicht mehr benötigt werden. Aber was, wenn wir eine andere Funktion aufrufen wollten, um ein dynamisches Objekt zu zerstören und den zugewiesenen Speicher ordnungsgemäß zu bereinigen? Hier kommen benutzerdefinierte Deleter ins Spiel.
Was sind benutzerdefinierte Deleter?
Ein benutzerdefinierter Deleter ist eine Funktion oder ein Funktionsobjekt, das während der Erstellung mit einem Smart-Pointer verknüpft wird. Es definiert, wie das referenzierte Objekt zerstört werden soll, wenn der Smart-Pointer den Gültigkeitsbereich verlässt. Benutzerdefinierte Deleter ermöglichen eine detailliertere Kontrolle über den Ressourcenbereinigungsprozess. Dieses Verhalten ermöglicht es Entwicklern, den Speicher für eine Vielzahl von Ressourcen effizient freizugeben, einschließlich Dateihandles, Verbindungen und benutzerdefinierter Datenstrukturen.
Praktische Anwendungsfälle
Betrachten wir ein praktisches Beispiel, um die Bedeutung von benutzerdefinierten Löschern zu erkennen. Angenommen, Sie arbeiten an einem Projekt, das den Umgang mit Dateien mit Smart-Pointern beinhaltet. Sie möchten sicherstellen, dass, wenn ein Smart-Pointer außer Gültigkeitsbereich gerät, auch die zugehörige Datei geschlossen wird. Dies stellt zwei Dinge sicher: Der dynamische Speicher wird freigegeben UND die Datei wird gleichzeitig ordnungsgemäß geschlossen. So können wir beides mit einem benutzerdefinierten Löscher erreichen:
main
#include <iostream> #include <memory> #include <fstream> void customFileDeleter(std::ofstream* file) { //check if file object is accessible and file is open if (file && file->is_open()) { file->close(); // Close the file } delete file; // Release memory } int main() { // Creating a smart pointer to a file with a custom deleter std::unique_ptr<std::ofstream, decltype(&customFileDeleter)> filePtr(new std::ofstream("example.txt"), &customFileDeleter); if (filePtr->is_open()) { *filePtr << "Writing to the file using a smart pointer with a custom deleter!\n"; } else { std::cout << "Failed to open the file!\n"; } // Smart pointer automatically closes the file when it goes out of scope }
Beim Erstellen des einzigartigen Pointers übergeben wir die Funktion customFileDeleter
, unseren benutzerdefinierten Löscher, als Template-Parameter. Das Schlüsselwort decltype
wird nur verwendet, um den Typ der Funktion zur Kompilierzeit zu extrahieren. Die Funktion customFileDeleter
ermöglicht es uns, Speicherfreigabe und Dateischließung in einer einzigen Funktion zu kombinieren.
Geteilte Zeiger und benutzerdefinierte Löscher
Um einem geteilten Zeiger einen benutzerdefinierten Löscher zuzuordnen, müssen wir den Löscher an den Konstruktor des geteilten Zeigers übergeben. Schauen wir uns ein einfaches Beispiel an:
main
#include <iostream> #include <memory> // Custom deleter function for a resource void customResourceDeleter(int* ptr) { std::cout << "Custom deleter called for resource at address: " << ptr << std::endl; delete ptr; } int main() { // Creating a shared pointer with a custom deleter std::shared_ptr<int> sharedPtrWithCustomDeleter(new int(42), customResourceDeleter); // Accessing the shared resource std::cout << "Shared pointer value: " << *sharedPtrWithCustomDeleter << std::endl; // The shared pointer automatically manages the resource using the custom deleter }
Im obigen Beispiel erstellen wir einen geteilten Zeiger auf einen Integer und übergeben die benutzerdefinierte Löscherfunktion als Argument an den Konstruktor.
Danke für Ihr Feedback!