Intelligente Zeiger in C++
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 15 von 104.
Smart Pointer sind Wrapper-Klassen, die den Heap-Speicher automatisch für Sie verwalten. Sie machen manuelle delete-Aufrufe überflüssig, indem sie den Speicher bereinigen, wenn der Pointer seinen Gültigkeitsbereich verlässt.
Binden Sie den <memory>-Header ein, um Smart Pointer zu verwenden.
unique_ptr – exklusives Eigentum. Zu jedem Zeitpunkt kann nur ein Zeiger die Ressource besitzen.
#include <memory>
std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack(); // Verwendung wie ein normaler Zeiger
// Kann nicht kopiert werden, aber der Besitz kann übertragen werden
std::unique_ptr<Player> player2 = std::move(player);
// player ist jetzt nullptrshared_ptr – gemeinsamer Besitz. Mehrere Zeiger können dieselbe Ressource besitzen. Der Speicher wird freigegeben, wenn der letzte Besitzer zerstört wird.
std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1; // Beide besitzen die Ressource
std::cout << p1.use_count(); // Gibt 2 ausweak_ptr – nicht besitzender Beobachter eines shared_ptr. Nützlich zum Aufbrechen zirkulärer Verweise.
std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;
if (auto locked = weak.lock()) { // In shared_ptr umwandeln
locked->attack();
}Verwenden Sie standardmäßig unique_ptr für alleiniges Eigentum. Verwenden Sie shared_ptr, wenn mehrere Objekte eine Ressource gemeinsam nutzen müssen. Verwenden Sie weak_ptr, um zu beobachten, ohne die Lebensdauer zu verlängern.
Bevorzugen Sie make_unique und make_shared gegenüber einfachem new.
Aufgabe
EinfachLassen Sie uns ein Dokumentenfreigabesystem erstellen, das die verschiedenen Eigentumsmodelle von Smart Pointern demonstriert. Sie werden sehen, wie unique_ptr exklusives Eigentum erzwingt, wie shared_ptr mehrere Eigentümer ermöglicht und wie weak_ptr beobachten kann, ohne die Lebensdauer zu beeinflussen.
Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:
Document.h: Definieren Sie eine KlasseDocument, die ein freigebbares Dokument darstellt. Sie sollte Folgendes enthalten:- Ein privates Attribut
title(String) - Einen Konstruktor, der einen Titel entgegennimmt und
"Document created: <title>"ausgibt - Einen Destruktor, der
"Document deleted: <title>"ausgibt - Eine Methode
getTitle(), die den Titel zurückgibt
- Ein privates Attribut
main.cpp: Demonstrieren Sie alle drei Smart-Pointer-Typen, indem Sie einen Dokumenttitel aus der Eingabe lesen und dann:- Einen
unique_ptrauf ein Document mit dem eingegebenen Titel erstellen "Unique owner: <title>"ausgeben- Das Eigentum mit
std::moveauf einen anderenunique_ptrübertragen "Ownership transferred"ausgeben- Einen
shared_ptrauf ein neues Document mit dem Titel"SharedDoc"erstellen - Einen zweiten
shared_ptrerstellen, der auf dasselbe Dokument zeigt "Shared owners: <count>"unter Verwendung vonuse_count()ausgeben- Einen
weak_ptrvon einem der Shared Pointer erstellen lock()verwenden, um über den Weak Pointer auf das Dokument zuzugreifen und"Weak access: <title>"auszugeben
- Einen
Denken Sie daran, <memory> für Smart Pointer einzubinden. Verwenden Sie std::make_unique und std::make_shared, um Ihre Smart Pointer zu erstellen. Die Destruktor-Meldungen helfen Ihnen zu sehen, wann jedes Dokument am Ende des Programms automatisch bereinigt wird.
Binden Sie Ihre Header-Datei in main.cpp mit #include "Document.h" ein.
Probier es selbst
#include <iostream>
#include <memory>
#include <string>
#include "Document.h"
using namespace std;
int main() {
string inputTitle;
cin >> inputTitle;
// TODO: Erstelle einen unique_ptr für ein Document mit inputTitle
// unter Verwendung von std::make_unique
// TODO: Gib "Unique owner: <title>" aus
// TODO: Übertrage den Besitz auf einen anderen unique_ptr mittels std::move
// TODO: Gib "Ownership transferred" aus
// TODO: Erstelle einen shared_ptr für ein neues Document mit dem Titel "SharedDoc"
// unter Verwendung von std::make_shared
// TODO: Erstelle einen zweiten shared_ptr, der auf dasselbe Dokument zeigt
// TODO: Gib "Shared owners: <count>" unter Verwendung von use_count() aus
// TODO: Erstelle einen weak_ptr von einem der Shared Pointer
// TODO: Verwende lock(), um über den weak_ptr auf das Dokument zuzugreifen
// und gib "Weak access: <title>" aus
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamespaces & GültigkeitsbereichEinführung in OOP mit C++Klassen vs. ObjekteDer „this“-ZeigerMethoden (Member-Funktionen)Attribute (Datenmember)Grundlagen zu Ctors & DtorsRückblick – Einfacher Taschenrechner4Klassenattribute
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen und -KlassenZusammenfassung – Bankkontoverwaltung7Vererbung
Grundlagen der VererbungZugriffsebenen bei der VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick – Mitarbeiterhierarchie2Speicherverwaltung
Stack- vs. Heap-SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Intelligente Zeiger in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsbezeichner in C++Zugriffsbezeichner im DetailInformationsverbergungStruct vs. KlasseVerschachtelte und innere KlassenWiederholung – Studierendenverwaltungssystem8Polymorphie
Polymorphie zur Compilezeit vs. LaufzeitFunktionsüberladungVirtuelle Funktionen erneut betrachtetRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIRückblick – Shape-Calculator3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorMove-KonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktor im DetailDrei-/Fünf-/Null-RegelZusammenfassung – String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladung der Operatoren [] und ()TypkonvertierungsoperatorenWiederholung – Matrix-Klasse9Templates
FunktionstemplatesKlassen-TemplatesTemplate-SpezialisierungVariadische TemplatesGrundlagen zu SFINAE und Type TraitsRückblick – Generischer ContainerÜbe selbstständig: Online-C++-Compiler