Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

C++: Smart Pointer

Einen unique_ptr erzeugen

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Diese Variante eines Smartpointers kann nicht kopiert werden. In diesem Film erfahren Sie, weshalb das manchmal genau das ist, was Sie haben wollen.
06:59

Transkript

Ein Uniquepointer ist ein Smartpointer, der nicht kopiert werden kann. Es gibt immer nur ein einziges Exemplar dieses Zeigers, sodass Sie ihn auch nicht versehentlich kopieren können, und es niemals einen Zweifel darüber gibt, wer ihn besitzt. Ich habe hier eine Arbeitskopie der Datei unique_ptr.cpp aus den Übungsdateien, außerdem habe ich die Klasse "strc" in diesem Projekt geöffnet. Die Klasse "strc" ist eine einfache Stringklasse mit Ausgabeanweisungen für alle Konstruktoren und Destruktoren, und wie Sie hier sehen, geht das mit "msg". Wenn ich hier ganz nach oben gehe, sehen Sie eine "msg" für den Standardkonstruktor, eine "msg" für den C-Stringkonstruktor und so weiter, für alle Konstruktoren den Destruktor, sowie den Kopier- und Vertauschungsoperator. Hier soll vor allem gezeigt werden, wie Smartpointer ein Objekt verwalten. Sie erzeugen also einen Uniquepointer, und hier erzeugen Sie einen Uniquepointer genau auf die gleiche Weise, wie Sie irgendein anderes Vorlagenobjekt erzeugen würden. Wir haben hier die Signatur der Templateklasse "std: :unique_ptr", der Typ ist "strc". Es folgen der Name des zu erzeugenden Objekts, und in Klammern ein Ausdruck für das Erstellen des Objekts. Der Operator "new" gibt natürlich einen Zeiger zurück, und genau diesen brauchen wir, um einen Smartpointer zu konstruieren. Ich erstelle nun das Projekt und führe es aus. Wenn ich hier ganz nach oben an den Anfang scrolle, sehen Sie, dass unique pointer one erstellt wird. Ich zeige ihn mit dieser Displayfunktion an, die folgendermaßen aussieht: Wie hier zu sehen ist, gibt sie lediglich one aus, und Sie können auch sehen, dass der Konstruktor in "strc" aufgerufen wird, somit konstruiert der Operator "new" ein neues Objekt, und übernimmt seine Adresse als Zeiger, und dies passiert unmittelbar hier, im "cstring" Konstruktor, weil ich einen "cstring" an den "strc"-Konstruktor übergebe. Das ist also der typische Weg, um einen Uniquepointer zu erzeugen. Seit C++14 gibt es eine Template-Funktion "make_unique", die aber in diesem Compiler nicht unterstützt wird. Andererseits handelt es sich nur um eine ziemlich einfache Funktion, die sich problemlos in eigener Regie erzeugen lässt. Ich habe sie hier also eingebunden, und zwar im namespace "notstd", und ich verwende sie mit "notstd: :make_unique", und dem Typ, sowie mit dem, was im Konstrukt an Klammern steht. Somit bildet diese kleine Template-Funktion nach, was make_unique in C++14 bewerkstelligt. Ich habe sie hier deshalb eingebunden, damit Sie sehen können, wie das alles vonstatten geht. Das sollte der korrekte Weg sein, um einen Uniquepointer zu erzeugen, und immer mehr Compiler werden ihn unterstützen. Der Microsoft Visual C++ Compiler, der zu Visual Studio 2013 gehört, unterstützt derzeit bereits make_unique, deshalb habe ich diese Funktion an diesem namespace notstd untergebracht. Wenn Sie einen Compiler haben, der "make_unique" unterstützt, nehmen Sie einfach das "not" weg, und "std: :make_unique" funktioniert. Hier klappt das allerdings nicht, weil es im namespace "std" kein "make_unique "gibt. Hier sind also einige Dinge, die sich mit einem Uniquepointer bewerkstelligen lassen. Die Methode "reset" wird verwendet, um ein Objekt zu zerstören, und sie eignet sich auch, um das Objekt durch ein neues zu ersetzen. Der Destruktor des Objekts wird also aufgerufen, wenn "reset" aufgerufen wird. Und dann wird der "new"-Constructor aufgerufen, und das neue Objekt ersetzt das alte Objekt. Und wenn ich hier a und b mit Display anzeige, erhalte ich three und two. Dabei ist b gleich two, und a wird nun durch three ersetzt. Einen Zeiger kann ich auch verschieben, b und c sind Zeiger, denn b ist ein Zeiger, und somit liefert move einen Zeiger zurück. Und auto erzeugt einen anderen Zeiger desselben Typs. Somit wird er einfach verschoben, und weder ein Konstruktor noch ein Destruktor muss aufgerufen werden. Praktisch ist das eine wirklich schnelle und effiziente Art und Weise, Zeiger zu verschieben, und da dies ein Uniquepointer ist, kann er natürlich nicht kopiert werden, wenn ich also versuche, dies einfach zuzuweisen, ohne es zu kopieren, wird mir das gleich als Fehler angekreidet. Wenn ich versuche, das Projekt zu erstellen, erhalte ich die folgende Fehlermeldung: "Call to implicitly deleted copy constructor" weil es für den Uniquepointer keinen Kopierkonstruktor gibt. Und deshalb funktioniert die Move-Version, wie wir hier unten sehen können. Um ein Objekt zu zerstören, ruft man einfach die Methode reset auf. Der Smartpointer kümmert sich um den Aufruf des Destruktors, und Sie sehen, dass nun a und b zerstört wurden, weil hier oben b aus dem Weg geräumt, verschoben habe. Und ich kann genauso auch "reset b" aufrufen, der Uniquepointer besitzt zwar auch eine Release-Methode, doch können sie damit nicht das Objekt durch ein neues ersetzen. Die Wirkung der Methode ist gleich, außer, dass sie den Destruktor nicht aufruft, Meistens werden wir also "reset" statt "release" verwenden. Ein wichtiger Punkt, der nicht gleich ins Auge sticht, ist der, dass man einen Uniquepointer nicht an eine Funktion übergeben kann, zumindest nicht in der üblichen Art und Weise. Zur Veranschaulichung erstelle ich eine einfache Funktion f. Sie übernimmt einen Standard-Uniquepointer, von strc, den wir p nennen, und wir geben hier eine Meldung aus, die besagt, dass wir f aufgerufen haben. Außerdem zeigen wir p an. Und nun versuche ich einmal, a an die Funktion zu übergeben, und zwar mit f von a wie hier, und wenn sich der Compiler damit zu befassen hat, erhalten wir die gleiche Fehlermeldung: "Call to implicitly-deleted copy constructor" Der Grund dafür ist, dass wir den Zeiger als Wert übergeben, Dieses Zeigerobjekt, dieses Smartpoint- Objekt, kann nicht kopiert werden, weil es sich um einen Uniquepointer handelt. Wenn ich also einen Uniquepointer in eine Funktion übergeben will, muss ich stattdessen seine Referenz nehmen, das heißt nichts anderes, als die Referenz des Zeigeobjekts zu verwenden, und wenn ich das Projekt nun kompiliere und ausführe, und hier ganz nach oben scrolle, sehen Sie, dass es jetzt funktioniert. Wir rufen die Funktion f auf, und sie liefert den Wert one, weil wir ihn an a übergeben. Einen Zeiger können Sie zwar nicht als Wert an eine Funktion übergeben, doch Sie können eine Referenz auf einen beliebigen Zeiger wie diesen übergeben, weil die Referenz natürlich nicht versucht, eine Kopie des Zeigers zu erzeugen. Somit sind Uniquepointer ein wertvolles Tool, um den Speicher zu verwalten, und Speicherlecks zu reduzieren. Manchmal jedoch braucht man wirklich mehrere Kopien von Zeigern, und hierfür haben wir gemeinsame Zeiger, Sharepointer, mit denen wir uns in der nächsten Lektion beschäftigen.

C++: Smart Pointer

Lernen Sie die verschiedenen Typen von intelligenten Zeigern kennen, wie sie eingesetzt werden und wie sie funktionieren.

29 min (8 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Software:
Exklusiv für Abo-Kunden
Erscheinungsdatum:13.12.2016

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!