Inhoudsopgave:
- Stap 1: Maak je klas, met headerbestand en CPP-bestand
- Stap 2: Stel de constructor in op privé
- Stap 3: Stel de Destructor in op Privé
- Stap 4: Een statische aanwijzervariabele maken in de Singleton
- Stap 5: Een instantiefunctie maken
- Stap 6: Statische openbare functies maken
- Stap 7: De beëindigingsfunctie maken
- Stap 8: PtrInstance instellen op Nullptr
- Stap 9: Test en conclusie
Video: Hoe het Singleton-ontwerppatroon in C ++ te doen: 9 stappen
2024 Auteur: John Day | [email protected]. Laatst gewijzigd: 2024-01-30 11:17
Invoering:
Het doel van deze instructiegids is om de gebruiker te leren hoe hij het singleton-ontwerppatroon in zijn C++-programma kan implementeren. Daarbij zal deze instructieset de lezer ook uitleggen waarom elementen van een singleton zijn zoals ze zijn en hoe de code wordt verwerkt. Dit wetende, zal in de toekomst helpen bij het debuggen van je toekomstige singletons. Wat is het singleton-ontwerppatroon? Het singleton-ontwerppatroon is een ontwerppatroon waarbij de codeur een klasse creëert die slechts één keer kan worden geïnstantieerd, de openbare functies van de klassen zijn in principe overal toegankelijk, op voorwaarde dat u het headerbestand #included in andere projectgerelateerde bestanden.
Het singleton-ontwerppatroon is een onmisbaar ontwerppatroon voor elke objectgeoriënteerde programmeur, softwareprogrammeurs en gameprogrammeurs. Het singleton-ontwerppatroon is ook een van de gemakkelijkste coderingsontwerppatronen die er zijn. Door het te leren, kun je in de toekomst andere, moeilijkere ontwerppatronen leren. Het kan je ook helpen om de code van je programma te stroomlijnen op manieren waarvan je dacht dat het niet mogelijk was.
Hoewel de moeilijkheidsgraad van het singleton-ontwerppatroon eenvoudig is in vergelijking met andere ontwerppatronen, heeft deze instructieset een gemiddelde moeilijkheidsgraad. Dit betekent dat om deze instructies uit te voeren, we u aanraden de basis- en geavanceerde syntaxisvereisten van C++ te kennen. U moet ook de juiste C++-coderingetiquette kennen (d.w.z. klassevariabelen privé houden, één klasse per headerbestand enz.). Je moet ook weten hoe je geheugen vrijmaakt en hoe constructors en destructors werken in C++.
Deze instructiegids duurt gemiddeld ongeveer 10-15 minuten.
Materiaalvereisten:
-Een computer (kan pc of Mac zijn) waarop Visual Studios kan worden uitgevoerd (elke versie)
-Een eenvoudig programma, gemaakt in Visual Studios, waarmee u uw singleton kunt testen
Opmerking: het singleton-ontwerppatroon kan worden uitgevoerd op elke andere C++-ondersteunende IDE- of coderingsinterface, maar voor deze instructieset gebruiken we Visual Studios Enterprise Edition.
Stap 1: Maak je klas, met headerbestand en CPP-bestand
Om deze twee bestanden en de klasse in één keer te maken, opent u uw project / programma in Visual Studios, gaat u naar de oplossingsverkenner, klikt u met de rechtermuisknop en er verschijnt een vak in de buurt van uw muiscursor, zoek de optie "Toevoegen", zweef eroverheen, en een ander vak zou aan de rechterkant moeten verschijnen. In dit vak wilt u de optie "Nieuw item…" vinden, klik erop en een venster dat lijkt op de onderstaande foto 1.1-afbeelding zou moeten verschijnen. In dit venster wilt u "C++ Class" selecteren en vervolgens op "Toevoegen" klikken. Dit opent een ander venster dat lijkt op de afbeelding van foto 1.2. In dit venster typt u de naam van uw klas in het veld "Klassenaam" en Visual Studios zal automatisch het eigenlijke bestand een naam geven achter de klasnaam. Voor het doel van deze instructie gaan we onze klasse "EngineDebugSingleton" noemen, maar het kan elke op letters gebaseerde naam zijn. U kunt nu op "OK" klikken en doorgaan naar stap 2.
Opmerking: de oplossingsverkenner en waar de bestanden op uw computer worden bewaard, zijn gescheiden. Als u iets in de oplossingsverkenner verplaatst of maakt, worden de bestanden niet verplaatst of georganiseerd in uw OS-bestandsverkenner. Een veilige manier om uw bestanden aan de kant van de bestandsverkenner te ordenen zou zijn om de specifieke bestanden uit de verkenner te verwijderen, maar niet om de specifieke bestanden uit de verkenner te verwijderen, dezelfde bestanden in de verkenner naar de gewenste locatie te verplaatsen en dan terug te gaan naar de verkenner, klik met de rechtermuisknop, zoek de optie "Toevoegen", zoek vervolgens "Bestaand item" en zoek de bestanden die u hebt verplaatst. Zorg ervoor dat u zowel het header- als het cpp-bestand verplaatst.
Stap 2: Stel de constructor in op privé
Met uw nieuw gemaakte CPP-bestand en headerbestand, als het niet automatisch werd geopend toen u het maakte, gaat u naar de oplossingsverkenner en klikt u op en opent u de "EngineDebugSingleton.h". U wordt dan begroet met een "EngineDebugSingleton()", de standaardconstructor van de klasse en "~EngineDebugSingleton()" de klassenvernietiger. Voor deze stap willen we de constructor op privé zetten, dit betekent dat deze functie alleen beschikbaar is voor de klasse en niets anders. Hiermee kun je geen variabele maken of de klasse aan het geheugen toewijzen buiten de klasse, alleen in het headerbestand van de klassen en de andere functies van de klassen. Het privé hebben van de constructor is de sleutel tot het ontwerppatroon en hoe singletons werken. We zullen in toekomstige stappen ontdekken hoe een singleton wordt geïnstantieerd en benaderd.
De klasse zou er nu zo uit moeten zien nadat de constructor naar privé is verplaatst (kijk naar de bijbehorende foto)
Stap 3: Stel de Destructor in op Privé
Zoals we deden met de constructor in
stap 2, voor deze stap stellen we de destructor nu in op privé. Net als bij de constructor kan niets, behalve de klasse zelf, variabelen van de klasse uit het geheugen verwijderen.
De klas zou er nu zo uit moeten zien na het voltooien van deze stap. (Zie bijbehorende foto)
Stap 4: Een statische aanwijzervariabele maken in de Singleton
In deze stap maken we een
statische aanwijzervariabele van het type "EngineDebugSingleton*". Dit zal de variabele zijn die zal worden gebruikt om onze singleton aan het geheugen toe te wijzen en zal ernaar verwijzen gedurende de hele tijd dat onze singleton aan het geheugen is toegewezen.
Dit is hoe ons headerbestand eruit zou moeten zien na het maken van deze variabele
Stap 5: Een instantiefunctie maken
We willen nu een instantie maken
functie. De functie moet een statische functie zijn en een verwijzing naar onze klasse willen retourneren ("EngineDebugSingleton&"). We hebben onze functie Instance() aangeroepen. In de functie zelf zullen we eerst willen testen of ptrInstance == nullptr (kan worden ingekort tot !ptrInstance), als het nullptr is, betekent dit dat de singleton niet is toegewezen en in het kader van de if-instructie zullen we wilt toewijzen door ptrInstance = new EngineDebugSingleton() te doen. Dit is waar u de singleton daadwerkelijk aan het geheugen toewijst. Nadat we het bereik van de if-instructie hebben verlaten, zullen we retourneren waarnaar ptrInstance verwijst, wat wordt aangegeven door de syntaxis "*ptrInstance". We zullen deze functie intensief gebruiken bij het maken van onze statische openbare functies, zodat we kunnen controleren of de singleton is gemaakt en aan het geheugen is toegewezen. In wezen zorgt deze functie ervoor dat u slechts één toewijzing van de klasse kunt hebben en niet meer.
Dit is hoe onze klasse er nu uit zou moeten zien na het maken van de functie Instance(). Zoals je kunt zien, is alles wat we hebben gedaan in het privégedeelte van de klas gebleven, dit zal in de volgende paar stappen een beetje veranderen.
Stap 6: Statische openbare functies maken
Nadat je de functie hebt gemaakt van
stap 5, kunt u beginnen met het maken van statische openbare functies. Elke publieke functie zou een private functie moeten hebben, de naam van deze functie mag niet hetzelfde zijn. Waarom de functie Statisch maken? We maken de openbare functies statisch, zodat ze toegankelijk zijn zonder een echt object. Dus in plaats van iets te doen als "EngineDebugSingleObj->SomeFunction()", doen we "EngineDebugSingleton:: Some Function()". Dit maakt het mogelijk dat een singleton in principe overal in code kan worden benaderd, op voorwaarde dat je #het headerbestand hebt opgenomen in het specifieke projectbestand waarmee je werkt. Hiermee kun je de singleton ook maken via een van zijn openbare functies.
Voor onze doeleinden hebben we in deze stap twee openbare statische leegte-functies gemaakt, "add()" en "subtract()". In het privégedeelte hebben we nog twee functies, "PrivAdd()" en "PrivSubtract()". We hebben ook een int-variabele toegevoegd met de naam "NumberOfThings". De definitie voor deze functies gaat naar het CPP-bestand van onze klassen. Om de functie gemakkelijk in het CPP-bestand te krijgen, markeert u met uw cursor de functie, die een groene lijn eronder zou moeten hebben, en drukt u op "Links ALT + ENTER", het geeft u de optie om de definitie in de klassen' gekoppelde CPP-bestand. Zie Foto 6.1 om te zien hoe het headerbestand eruit moet zien en nadat u alle functiedefinities hebt gemaakt, zou uw CPP eruit moeten zien als Foto 6.2, behalve dat uw functiedefinities geen code bevatten.
U wilt nu dezelfde code als in Foto 6.2 toevoegen aan uw functiedefinities. Zoals eerder vermeld, zullen onze openbare functies gebruik maken van de functie Instance(), die teruggeeft waarnaar ptrInstance verwijst. Dit geeft ons toegang tot de privéfuncties van onze klas. Met de openbare functie van een singleton zou u alleen die instantiefunctie moeten aanroepen. De enige uitzondering hierop is onze functie Beëindigen.
Opmerking: de exacte openbare en privéfuncties die in deze stap worden getoond, zijn niet nodig, u kunt verschillende functienamen en bewerkingen hebben in de privéfunctie, maar voor elk type openbare functie moet u een privéfunctie hebben die daarbij hoort en de openbare functie moet in ons geval altijd de functie Instance() gebruiken.
Stap 7: De beëindigingsfunctie maken
Omdat we onze singleton alleen uit het geheugen in onze klasse kunnen deloceren, moeten we een statische openbare functie maken. Deze functie roept delete op ptrInstance aan, die de klassendestructor aanroept en dan willen we ptrInstance terugzetten op nullptr zodat het opnieuw kan worden toegewezen als je programma niet eindigt. U zult ook uw Singletons willen beëindigen om al het toegewezen geheugen op te schonen dat u hebt toegewezen aan de privévariabelen van Singleton.
Stap 8: PtrInstance instellen op Nullptr
Om uw singleton te voltooien, gaat u naar EngineDebugSingleton. CPP-bestand en typt u bovenaan het CPP-bestand in ons geval "EngineDebugSingleton* EngineDebugSingleton::ptrInstance = nullptr."
Als u dit doet, wordt ptrInstance in eerste instantie ingesteld op nullptr, dus wanneer u voor het eerst de instantiefunctie voor de eerste keer doorloopt, mag onze klasse worden toegewezen aan geheugen. Zonder dit krijgt u hoogstwaarschijnlijk een foutmelding omdat u probeert toegang te krijgen tot geheugen waaraan niets is toegewezen.
Stap 9: Test en conclusie
We zullen nu onze singleton willen testen om er zeker van te zijn dat deze werkt, dit houdt in dat we de openbare functies aanroepen zoals beschreven in stap 6 en we raden u aan breekpunten in te stellen om door uw code te stappen en te zien dat de singleton werkt zoals het zou moeten zijn. Ons startpunt bevindt zich in de main.cpp van ons project en onze main.cpp ziet er nu uit als de onderstaande afbeelding.
Gefeliciteerd! Je hebt zojuist je eerste implementatie van het Singleton Design Pattern voltooid. Met dit ontwerppatroon kunt u uw code nu op verschillende manieren stroomlijnen. U kunt nu bijvoorbeeld managersystemen maken die gedurende de looptijd van uw programma werken en die via statische functies overal waar u de klas hebt opgenomen, toegankelijk zijn.
Uw uiteindelijke headerbestand zou eruit moeten zien als de foto 7.1. Het bijbehorende CPP-bestand van uw singleton zou eruit moeten zien als Foto 6.2 met toevoeging van, bovenaan het bestand, van de code die wordt getoond in stap 8. Deze instructie gaf u een eenvoudige structuur van het Singleton Design Pattern.
Advies voor probleemoplossing:
Krijgt u geheugengerelateerde fouten?
Zorg ervoor dat u stap 7 en stap 8 raadpleegt om er zeker van te zijn dat u ptrInstance instelt op nullptr.
Oneindige lus optreedt?
Zorg ervoor dat je voor de publieke functies, in hun definities, de private functie noemt, niet dezelfde publieke functie.
Objecten toegewezen binnen de singleton die geheugenlekken veroorzaken?
Zorg ervoor dat je de beëindigingsfunctie van je singleton aanroept wanneer dat van toepassing is in je programmacode, en zorg ervoor dat je in de destructor van je singleton alle objecten die aan het geheugen zijn toegewezen binnen het bereik van de singleton-code de-toewijzing ongedaan maakt.