Inhaltsverzeichnis:

So erstellen Sie das Singleton-Entwurfsmuster in C++ - Gunook
So erstellen Sie das Singleton-Entwurfsmuster in C++ - Gunook

Video: So erstellen Sie das Singleton-Entwurfsmuster in C++ - Gunook

Video: So erstellen Sie das Singleton-Entwurfsmuster in C++ - Gunook
Video: 041 - Singleton-Klasse - C++ Tutorial Deutsch 2024, Juni
Anonim
So erstellen Sie das Singleton-Entwurfsmuster in C++
So erstellen Sie das Singleton-Entwurfsmuster in C++

Einführung:

Der Zweck dieser Anleitung besteht darin, dem Benutzer beizubringen, wie das Singleton-Entwurfsmuster in seinem C++-Programm implementiert wird. Dabei erklärt dieser Befehlssatz dem Leser auch, warum Elemente eines Singletons so sind und wie der Code verarbeitet wird. Wenn Sie dies wissen, können Sie in Zukunft beim Debuggen Ihrer zukünftigen Singletons helfen. Was ist das Singleton-Designmuster? Das Singleton-Design-Pattern ist ein Design-Pattern, bei dem der Coder eine Klasse erstellt, die nur einmal instanziiert werden kann. Auf die öffentlichen Funktionen der Klassen kann grundsätzlich überall zugegriffen werden, vorausgesetzt, Sie haben die Header-Datei in andere projektbezogene Dateien eingebunden.

Das Singleton-Designmuster ist ein Muss für jeden objektorientierten Programmierer, Softwareprogrammierer und Spieleprogrammierer. Das Singleton-Designmuster ist auch eines der einfachsten Codierungsdesignmuster auf dem Markt. Wenn Sie es lernen, können Sie in Zukunft andere, schwierigere Designmuster erlernen. Es kann Ihnen auch helfen, den Code Ihres Programms auf eine Weise zu optimieren, die Sie nicht für möglich gehalten haben.

Während der Schwierigkeitsgrad des Singleton-Designmusters im Vergleich zu anderen Designmustern einfach ist, hat dieser Befehlssatz einen mittleren Schwierigkeitsgrad. Dies bedeutet, dass wir für diese Anweisungen empfehlen, die grundlegenden und erweiterten Syntaxanforderungen von C++ zu kennen. Sie sollten auch die richtige C++-Codierungsetikette kennen (d. h. Klassenvariablen privat halten, eine Klasse pro Headerdatei usw.). Sie sollten auch wissen, wie Sie Speicher freigeben und wie Konstruktoren und Destruktoren in C++ funktionieren.

Diese Anleitung wird im Durchschnitt etwa 10-15 Minuten dauern.

Materialanforderungen:

-Ein Computer (kann ein PC oder Mac sein), auf dem Visual Studios ausgeführt werden kann (jede Version)

-Ein einfaches Programm, erstellt in Visual Studios, mit dem Sie Ihren Singleton testen können

Hinweis: Das Singleton-Entwurfsmuster kann auf jeder anderen C++-unterstützenden IDE oder Programmierschnittstelle ausgeführt werden, aber für diesen Befehlssatz verwenden wir Visual Studios Enterprise Edition.

Schritt 1: Erstellen Sie Ihre Klasse mit Header-Datei und CPP-Datei

Erstellen Sie Ihre Klasse mit Header-Datei und CPP-Datei
Erstellen Sie Ihre Klasse mit Header-Datei und CPP-Datei
Erstellen Sie Ihre Klasse mit Header-Datei und CPP-Datei
Erstellen Sie Ihre Klasse mit Header-Datei und CPP-Datei

Um diese beiden Dateien und die Klasse auf einmal zu erstellen, öffnen Sie Ihr Projekt / Programm in Visual Studios, gehen Sie zum Lösungs-Explorer, klicken Sie mit der rechten Maustaste und ein Feld sollte in der Nähe Ihres Mauszeigers angezeigt werden. Suchen Sie die Option "Hinzufügen", schweben Sie darüber, und rechts sollte ein weiteres Kästchen erscheinen. In diesem Feld möchten Sie die Option "Neuer Artikel…" finden, klicken Sie darauf und ein Fenster, das dem Bild 1.1 unten ähnelt, sollte erscheinen. In diesem Fenster möchten Sie „C++-Klasse“auswählen und dann auf „Hinzufügen“klicken. Dadurch wird ein weiteres Fenster geöffnet, das dem Bild von Foto 1.2 ähnelt. In diesem Fenster geben Sie den Namen Ihrer Klasse in das Feld „Klassenname“ein und Visual Studios benennt die eigentliche Datei automatisch nach dem Klassennamen. Zu diesem Zweck nennen wir unsere Klasse "EngineDebugSingleton", aber es kann ein beliebiger buchstabenbasierter Name sein. Sie können nun auf „OK“klicken und mit Schritt 2 fortfahren.

Hinweis: Der Lösungs-Explorer und der Speicherort der Dateien auf Ihrem Computer sind getrennt. Durch das Verschieben oder Erstellen von Elementen im Lösungs-Explorer werden die Dateien in Ihrem Betriebssystem-Datei-Explorer nicht verschoben oder organisiert. Eine sichere Möglichkeit, Ihre Dateien auf der Seite des Datei-Explorers zu organisieren, besteht darin, die spezifischen Dateien aus dem Lösungs-Explorer zu entfernen, aber nicht zu löschen, dieselben Dateien im Datei-Explorer an den gewünschten Ort zu verschieben und dann zum Lösungs-Explorer zurückzukehren, mit der rechten Maustaste zu klicken, Suchen Sie die Option "Hinzufügen", suchen Sie dann nach "Vorhandenes Element" und suchen Sie die Dateien, die Sie verschoben haben. Stellen Sie sicher, dass Sie sowohl die Header- als auch die cpp-Datei verschieben.

Schritt 2: Setzen Sie den Konstruktor auf Privat

Setzen Sie den Konstruktor auf Privat
Setzen Sie den Konstruktor auf Privat

Wenn Ihre neu erstellte CPP-Datei und Header-Datei nicht automatisch geöffnet wurde, als Sie sie erstellt haben, gehen Sie zum Lösungs-Explorer und klicken Sie auf und öffnen Sie die Datei „EngineDebugSingleton.h“. Sie werden dann mit einem „EngineDebugSingleton()“, dem Standardkonstruktor der Klasse und „~EngineDebugSingleton()“, dem Klassendestruktor begrüßt. Für diesen Schritt wollen wir den Konstruktor auf private setzen, das heißt, diese Funktion steht nur der Klasse zur Verfügung und sonst nichts. Damit können Sie keine Variable erstellen oder die Klasse dem Speicher außerhalb der Klasse zuweisen, sondern nur in der Headerdatei der Klasse und den anderen Funktionen der Klasse. Der private Konstruktor ist der Schlüssel zum Entwurfsmuster und zur Funktionsweise von Singletons. Wir werden in zukünftigen Schritten herausfinden, wie ein Singleton instanziiert und darauf zugegriffen wird.

Die Klasse sollte jetzt so aussehen, nachdem der Konstruktor auf privat verschoben wurde (siehe zugehöriges Foto)

Schritt 3: Setzen Sie den Destruktor auf Private

Setzen Sie den Destruktor auf Privat
Setzen Sie den Destruktor auf Privat

Wie wir es mit dem Konstruktor in gemacht haben

Schritt 2, für diesen Schritt werden wir nun den Destruktor auf privat setzen. Wie beim Konstruktor kann nichts außer der Klasse selbst alle Variablen der Klasse aus dem Speicher löschen.

Die Klasse sollte jetzt so aussehen, nachdem Sie diesen Schritt abgeschlossen haben. (Siehe zugehöriges Foto)

Schritt 4: Erstellen einer statischen Zeigervariablen im Singleton

Erstellen einer statischen Zeigervariablen im Singleton
Erstellen einer statischen Zeigervariablen im Singleton

In diesem Schritt erstellen wir a

statische Zeigervariable vom Typ „EngineDebugSingleton*“. Dies ist die Variable, die verwendet wird, um unseren Singleton dem Speicher zuzuordnen und auf sie zu verweisen, während unser Singleton dem Speicher zugeordnet ist.

So sollte unsere Header-Datei aussehen, nachdem diese Variable erstellt wurde

Schritt 5: Erstellen einer Instanzfunktion

Erstellen einer Instanzfunktion
Erstellen einer Instanzfunktion

Wir wollen jetzt eine Instanz machen

Funktion. Die Funktion muss eine statische Funktion sein und eine Referenz auf unsere Klasse ("EngineDebugSingleton&") zurückgeben. Wir haben unsere Funktion Instanz() aufgerufen. In der Funktion selbst wollen wir zuerst testen, ob ptrInstance == nullptr (kann zu !ptrInstance abgekürzt werden), wenn es nullptr ist, bedeutet dies, dass das Singleton nicht zugewiesen wurde und im Geltungsbereich der if-Anweisung werden wir zuordnen möchten, indem Sie ptrInstance = new EngineDebugSingleton() ausführen. Hier weisen Sie den Singleton tatsächlich dem Speicher zu. Nachdem wir den Gültigkeitsbereich der if-Anweisung verlassen haben, geben wir zurück, worauf ptrInstance zeigt, was durch die Syntax „*ptrInstance“gekennzeichnet ist. Wir werden diese Funktion stark verwenden, wenn wir unsere statischen öffentlichen Funktionen erstellen, damit wir überprüfen können, ob das Singleton erstellt und dem Speicher zugewiesen wurde. Im Wesentlichen macht diese Funktion es so, dass Sie nur eine Zuordnung der Klasse haben können und nicht mehr.

So sollte unsere Klasse jetzt aussehen, nachdem die Funktion Instance() erstellt wurde. Wie Sie sehen können, ist alles, was wir gemacht haben, im privaten Bereich der Klasse geblieben, dies wird sich in den nächsten Schritten ein wenig ändern.

Schritt 6: Erstellen von statischen öffentlichen Funktionen

Statische öffentliche Funktionen erstellen
Statische öffentliche Funktionen erstellen
Statische öffentliche Funktionen erstellen
Statische öffentliche Funktionen erstellen
Statische öffentliche Funktionen erstellen
Statische öffentliche Funktionen erstellen

Nachdem Sie die Funktion aus

Schritt 5 können Sie damit beginnen, statische öffentliche Funktionen zu erstellen. Zu jeder öffentlichen Funktion sollte eine private Funktion gehören, der Name dieser Funktion darf nicht gleich sein. Warum die Funktion statisch machen? Wir machen die öffentlichen Funktionen statisch, damit auf sie ohne ein tatsächliches Objekt zugegriffen werden kann. Anstatt also etwas wie „EngineDebugSingleObj->SomeFunction()“zu machen, machen wir „EngineDebugSingleton:: Some Function()“. Dadurch kann auf einen Singleton praktisch überall im Code zugegriffen werden, vorausgesetzt, Sie haben die Header-Datei in die jeweilige Projektdatei, mit der Sie arbeiten, #eingeschlossen. Damit können Sie den Singleton auch über jede seiner öffentlichen Funktionen erstellen.

Für unsere Zwecke haben wir in diesem Schritt zwei öffentliche statische void-Funktionen erstellt, „add()“und „subtract()“. Im privaten Bereich haben wir zwei weitere Funktionen, „PrivAdd()“und „PrivSubtract()“. Wir haben auch eine int-Variable namens „NumberOfThings“hinzugefügt. Die Definition für diese Funktionen wird in die CPP-Datei unserer Klassen aufgenommen. Um die Funktion einfach in die CPP-Datei zu bekommen, markieren Sie mit dem Cursor die Funktion, die eine grüne Linie darunter haben sollte, und drücken Sie "Links ALT + ENTER". Klassen zugeordnete CPP-Datei. Sehen Sie sich Foto 6.1 an, um zu sehen, wie die Header-Datei aussehen sollte. Nachdem Sie alle Funktionsdefinitionen erstellt haben, sollte Ihr CPP wie Foto 6.2 aussehen, außer dass Ihre Funktionsdefinitionen keinen Code enthalten.

Sie möchten nun den gleichen Code wie in Foto 6.2 zu Ihren Funktionsdefinitionen hinzufügen. Wie bereits erwähnt, verwenden unsere öffentlichen Funktionen die Funktion Instance(), die zurückgibt, worauf ptrInstance zeigt. Dadurch können wir auf die privaten Funktionen unserer Klasse zugreifen. Bei jeder öffentlichen Funktion eines Singletons sollten Sie nur diese Instanzfunktion aufrufen. Die einzige Ausnahme hiervon ist unsere Terminate-Funktion.

Hinweis: Die genauen öffentlichen und privaten Funktionen, die in diesem Schritt gezeigt werden, sind nicht erforderlich, Sie können in der privaten Funktion unterschiedliche Funktionsnamen und Operationen haben, aber für jede Art von öffentlicher Funktion sollten Sie eine private Funktion dazu haben und die öffentliche Funktion sollte in unserem Fall immer die Funktion Instance() verwenden.

Schritt 7: Erstellen der Terminate-Funktion

Erstellen der Terminate-Funktion
Erstellen der Terminate-Funktion
Erstellen der Terminate-Funktion
Erstellen der Terminate-Funktion

Da wir in unserer Klasse nur unseren Singleton aus dem Speicher aufheben können, müssen wir eine statische öffentliche Funktion erstellen. Diese Funktion ruft delete auf ptrInstance auf, was den Klassendestruktor aufruft, und dann möchten wir ptrInstance wieder auf nullptr setzen, damit es erneut zugewiesen werden kann, wenn Ihr Programm nicht endet. Sie sollten Ihre Singletons auch beenden, um den zugewiesenen Speicher zu bereinigen, den Sie in den privaten Variablen eines Singletons zugewiesen haben.

Schritt 8: Setzen von PtrInstance auf Nullptr

Setzen von PtrInstance auf Nullptr
Setzen von PtrInstance auf Nullptr

Um Ihr Singleton zu vervollständigen, möchten Sie zur Datei EngineDebugSingleton. CPP wechseln und oben in der CPP-Datei in unserer Instanz "EngineDebugSingleton* EngineDebugSingleton::ptrInstance = nullptr" eingeben.

Dadurch wird ptrInstance zunächst auf nullptr gesetzt. Wenn Sie also die Instanzfunktion zum ersten Mal durchlaufen, darf unsere Klasse dem Speicher zugewiesen werden. Ohne sie erhalten Sie höchstwahrscheinlich einen Fehler, da Sie versuchen, auf einen Speicher zuzugreifen, dem nichts zugewiesen ist.

Schritt 9: Test und Fazit

Test und Fazit
Test und Fazit

Wir möchten nun testen, ob unser Singleton funktioniert, um sicherzustellen, dass er funktioniert. Dazu müssen wir die öffentlichen Funktionen wie in Schritt 6 beschrieben aufrufen und wir empfehlen Ihnen, Breakpoints einzurichten, um Ihren Code zu durchlaufen und zu sehen, dass der Singleton so funktioniert es sollte sein. Unser Ausgangspunkt wird in der main.cpp unseres Projekts sein und unsere main.cpp sieht jetzt wie in der Abbildung unten aus.

Herzliche Glückwünsche! Sie haben gerade Ihre erste Implementierung des Singleton Design Patterns abgeschlossen. Mit diesem Entwurfsmuster können Sie Ihren Code jetzt auf verschiedene Weise optimieren. Sie können jetzt beispielsweise Managersysteme erstellen, die während der Laufzeit Ihres Programms ausgeführt werden und auf die über statische Funktionen überall dort zugegriffen werden kann, wo Sie die Klasse eingefügt haben.

Ihre endgültige Header-Datei sollte wie in Foto 7.1 aussehen. Die mit Ihrem Singleton verknüpfte CPP-Datei sollte wie Foto 6.2 aussehen, wobei oben in der Datei der in Schritt 8 gezeigte Code hinzugefügt wurde. Diese Anweisung lieferte Ihnen eine einfache Struktur des Singleton-Designmusters.

Hinweise zur Fehlerbehebung:

Erhalten speicherbezogene Fehler?

Stellen Sie sicher, dass Sie Schritt 7 und Schritt 8 beachten, um sicherzustellen, dass Sie ptrInstance auf nullptr setzen.

Endlosschleife auftritt?

Stellen Sie sicher, dass Sie für die öffentlichen Funktionen in ihren Definitionen die private Funktion aufrufen und nicht dieselbe öffentliche Funktion.

Innerhalb des Singletons zugeordnete Objekte, die Speicherverluste verursachen?

Stellen Sie sicher, dass Sie die Termination-Funktion Ihres Singletons nach Bedarf in Ihrem Programmcode aufrufen, und stellen Sie im Destruktor Ihres Singletons sicher, dass Sie alle Objekte aufheben, die im Rahmen des Singleton-Codes dem Speicher zugewiesen wurden.