Innehållsförteckning:

Hur man gör Singleton -mönstret i C ++: 9 steg
Hur man gör Singleton -mönstret i C ++: 9 steg

Video: Hur man gör Singleton -mönstret i C ++: 9 steg

Video: Hur man gör Singleton -mönstret i C ++: 9 steg
Video: Gör overkliga ritningar snabbare med detta designmönster 2024, Juni
Anonim
Hur man gör Singleton -mönstret i C ++
Hur man gör Singleton -mönstret i C ++

Introduktion:

Syftet med denna instruktionsguide är att lära användaren hur man implementerar singleton -mönstret i sitt C ++ - program. Genom att göra detta kommer denna instruktionsuppsättning också att förklara för läsaren varför element i en singleton är som de är och hur koden behandlas. Att veta detta hjälper i framtiden med att felsöka dina framtida singletons. Vad är singleton -mönstret? Singleton -mönstret är ett designmönster där kodaren skapar en klass som bara kan instanseras en gång, klassernas offentliga funktioner kan i princip nås var som helst, förutsatt att du har #inkluderat rubrikfilen i andra projektrelaterade filer.

Singleton-mönstret är ett måste-känt designmönster för alla objektorienterade programmerare, programmerare och spelprogrammerare. Singleton -mönstret är också ett av de enklaste kodningsmodellerna som finns. Att lära sig det kan hjälpa dig att lära dig andra, svårare, designmönster i framtiden. Det kan också hjälpa dig att effektivisera programmets kod på sätt som du inte trodde var möjligt.

Medan svårigheten med singleton -mönstret är lätt jämfört med andra designmönster, har denna instruktionsuppsättning en medelstor svårighet. Det betyder att för att utföra dessa instruktioner rekommenderar vi att du känner till grundläggande och avancerade syntaxkrav för C ++. Du bör också känna till korrekt C ++ - kodningsetikett (dvs. behåll klassvariabler privata, en klass per rubrikfil etc.). Du bör också veta hur man frigör minne och hur konstruktörer och destruktorer fungerar i C ++.

Denna instruktionsguide tar i genomsnitt cirka 10-15 minuter.

Materialkrav:

-En dator (kan vara PC eller Mac) som kan köra Visual Studios (vilken version som helst)

-Ett enkelt program, skapat i Visual Studios, som du kan testa din singleton med

Obs: Singleton -mönstret kan göras på alla andra C ++ - stödjande IDE- eller kodningsgränssnitt, men för denna instruktionsuppsättning kommer vi att använda Visual Studios Enterprise Edition.

Steg 1: Skapa din klass med rubrikfil och CPP -fil

Skapa din klass, med rubrikfil och CPP -fil
Skapa din klass, med rubrikfil och CPP -fil
Skapa din klass, med rubrikfil och CPP -fil
Skapa din klass, med rubrikfil och CPP -fil

För att skapa dessa två filer och klassen på en gång, öppna ditt projekt / program i Visual Studios, gå till lösningsutforskaren, högerklicka, och en ruta ska dyka upp nära musmarkören, hitta alternativet "Lägg till", håll muspekaren över den, och en annan ruta ska visas till höger. I den här rutan vill du hitta alternativet "Nytt objekt..", klicka på det och ett fönster, som liknar bilden 1.1 -bilden nedan, ska visas. I det här fönstret vill du välja "C ++ Class" och sedan klicka på "Add". Detta öppnar ett annat fönster som liknar foto 1.2 -bilden. I det här fönstret skriver du in namnet på din klass i fältet "Klassnamn" och Visual Studios kommer automatiskt att namnge den faktiska filen efter klassnamnet. För den här instruktionens syfte kommer vi att döpa vår klass till "EngineDebugSingleton", men det kan vara vilket bokstavsbaserat namn som helst. Du kan nu trycka på "OK" och fortsätta till steg 2.

Obs! Lösningsutforskaren och där filerna finns på din dator är separata. Att flytta eller skapa något i lösningsutforskaren kommer inte att flytta eller organisera filerna i din OS -filutforskare. Ett säkert sätt att organisera dina filer på filutforskaren skulle vara att ta bort, men inte ta bort de specifika filerna från lösningsutforskaren, flytta samma filer i filutforskaren till önskad plats och gå sedan tillbaka till lösningsutforskaren, högerklicka, hitta alternativet "Lägg till", hitta "Befintligt objekt" och hitta de filer du flyttade. Se till att du flyttar både rubrik- och cpp -filen.

Steg 2: Ställ konstruktören på Privat

Ställ in konstruktören på Privat
Ställ in konstruktören på Privat

Med din nyskapade CPP -fil och rubrikfil, om den inte öppnades automatiskt när du skapade den, gå till lösningsutforskaren och klicka och öppna "EngineDebugSingleton.h". Du kommer då att hälsas med en "EngineDebugSingleton ()", klassens standardkonstruktör och "~ EngineDebugSingleton ()" klassdestruktorn. För det här steget kommer vi att vilja ställa konstruktorn till det privata, det betyder att denna funktion bara är tillgänglig för klassen och inget annat. Med detta kommer du inte att kunna göra en variabel eller tilldela klassen till minne utanför klassen, bara i klassens rubrikfil och klassernas andra funktioner. Att ha konstruktören privat är nyckeln till designmönstret och hur singletoner fungerar. Vi kommer att upptäcka i framtida steg hur en singleton instantieras och nås.

Klassen ska nu se ut så här efter att ha flyttat konstruktören till privat (Titta på tillhörande foto)

Steg 3: Ställ in Destructor på Privat

Ställ in Destructor på Privat
Ställ in Destructor på Privat

Som vi gjorde med konstruktören i

steg 2, för detta steg kommer vi nu att ställa in destruktorn till privat. Precis som med konstruktören kommer ingenting, förutom själva klassen, att kunna ta bort alla variabler i klassen från minnet.

Klassen ska nu se ut så här efter att ha slutfört detta steg. (Se tillhörande foto)

Steg 4: Skapa en statisk pekarvariabel i Singleton

Skapa en statisk pekarvariabel i Singleton
Skapa en statisk pekarvariabel i Singleton

I detta steg kommer vi att skapa en

statisk pekarvariabel av typen "EngineDebugSingleton*". Detta kommer att vara variabeln som kommer att användas för att tilldela vår singleton till minnet och kommer att peka på den under hela tiden som vår singleton tilldelas minne.

Så här ska vår header -fil se ut efter att ha skapat denna variabel

Steg 5: Skapa en instansfunktion

Skapa en instansfunktion
Skapa en instansfunktion

Vi vill nu göra en instans

fungera. Funktionen måste vara en statisk funktion och vill återlämna en referens till vår klass ("EngineDebugSingleton &"). Vi kallade vår funktion Instance (). I själva funktionen vill vi först testa om ptrInstance == nullptr (kan förkortas till! PtrInstance), om det är nullptr betyder det att singleton inte har tilldelats och inom ramen för if -satsen kommer vi att vill fördela genom att göra ptrInstance = new EngineDebugSingleton (). Det är här du faktiskt tilldelar singleton till minne. Efter att vi har lämnat omfånget av if -satsen kommer vi sedan att returnera det ptrInstance pekar på, vilket betecknas med syntaxen "*ptrInstance". Vi kommer att använda den här funktionen kraftigt när vi gör våra statiska offentliga funktioner, så att vi kan kontrollera om singleton har skapats och tilldelats minne. I huvudsak gör denna funktion det så att du bara kan ha en tilldelning av klassen och inte mer.

Så här ska vår klass se ut nu efter att ha skapat funktionen Instance (). Som du kan se har allt vi gjort stannat kvar i den privata delen av klassen, detta kommer att förändras lite i de närmaste stegen.

Steg 6: Skapa statiska offentliga funktioner

Skapa statiska offentliga funktioner
Skapa statiska offentliga funktioner
Skapa statiska offentliga funktioner
Skapa statiska offentliga funktioner
Skapa statiska offentliga funktioner
Skapa statiska offentliga funktioner

När du har gjort funktionen från

steg 5 kan du börja göra statiska offentliga funktioner. Varje offentlig funktion bör ha en privat funktion att följa med den, namnet på den här funktionen kan inte vara samma. Varför göra funktionen statisk? Vi gör de offentliga funktionerna statiska så att de kan nås utan ett verkligt objekt. Så istället för att göra något som "EngineDebugSingleObj-> SomeFunction ()", gör vi "EngineDebugSingleton:: Some Function ()". Detta gör det möjligt för en singleton att komma åt i princip var som helst i koden, förutsatt att du har #inkluderat rubrikfilen i den specifika projektfilen du arbetar med. Med detta kan du också skapa singleton genom någon av dess offentliga funktioner.

För våra ändamål i detta steg skapade vi två offentliga statiska ogiltiga funktioner, "add ()" och "subtract ()". I det privata avsnittet har vi ytterligare två funktioner, "PrivAdd ()" och "PrivSubtract ()". Vi har också lagt till en int -variabel som heter "NumberOfThings". Definitionen för dessa funktioner kommer att gå in i våra klasser CPP -fil. För att enkelt få funktionen att komma in i CPP -filen markerar du, med markören, funktionen, som ska ha en grön linje under den och trycker på "Vänster ALT + ENTER", det ger dig alternativet skapa definitionen i klassens associerade CPP -fil. Se Foto 6.1 för att se hur rubrikfilen ska se ut och efter att du har skapat alla funktionsdefinitioner ska din CPP se ut som Foto 6.2 förutom att dina funktionsdefinitioner inte har någon kod i dem.

Du kommer nu att vilja lägga till samma kod som i Foto 6.2 i dina funktionsdefinitioner. Som tidigare nämnts kommer våra offentliga funktioner att använda funktionen Instance (), som återger det ptrInstance pekar på. Detta gör att vi kan komma åt de privata funktionerna i vår klass. Med någon singletons offentliga funktion bör du bara kalla den Instance -funktionen. Det enda undantaget från detta är vår Avsluta -funktion.

Obs! De exakta offentliga och privata funktionerna som visas i det här steget är inte nödvändiga, du kan ha olika funktionsnamn och funktioner i den privata funktionen, men för alla typer av offentliga funktioner bör du ha en privat funktion för att följa den och den offentliga funktionen bör alltid använda funktionen Instance () i vårt fall.

Steg 7: Skapa avslutningsfunktionen

Skapa funktionen Avsluta
Skapa funktionen Avsluta
Skapa funktionen Avsluta
Skapa funktionen Avsluta

Eftersom vi bara kan lokalisera vår singleton från minnet i vår klass måste vi skapa en statisk offentlig funktion. Denna funktion kallar delete på ptrInstance, som kallar klassdestruktorn och sedan vill vi ställa tillbaka ptrInstance till nullptr så att det kan tilldelas igen om ditt program inte slutar. Du kommer också att vilja avsluta dina Singletons för att städa upp allt tilldelat minne som du har tilldelat i alla Singletons privata variabler.

Steg 8: Ställ in PtrInstance till Nullptr

Ställ in PtrInstance till Nullptr
Ställ in PtrInstance till Nullptr

För att slutföra din singleton vill du gå över till EngineDebugSingleton. CPP -filen och högst upp i CPP -filen, i vårt exempel, skriver du "EngineDebugSingleton* EngineDebugSingleton:: ptrInstance = nullptr."

Om du gör detta kommer ptrInstance initialt att ställas in på nullptr, så när du först går igenom instansfunktionen för första gången kommer vår klass att tilldelas minne. Utan det kommer du troligen att få ett fel eftersom du kommer att försöka komma åt minne som inte har något tilldelat det.

Steg 9: Test och slutsats

Test och slutsats
Test och slutsats

Vi kommer nu att vilja testa att vår singleton för att se till att det fungerar, detta kommer att innebära att vi kallar de offentliga funktionerna som beskrivs i steg 6 och vi rekommenderar att du ställer in brytpunkter för att gå igenom din kod och se att singleton fungerar som det borde vara. Vår utgångspunkt kommer att vara i vårt projekts main.cpp och vår main.cpp ser nu ut som bilden nedan.

Grattis! Du har just avslutat din första implementering av Singleton Design Pattern. Med detta designmönster kan du nu effektivisera din kod på olika sätt. Till exempel kan du nu skapa chefssystem som fungerar under programmets körtid, som kan nås via statiska funktioner var som helst där du har inkluderat klassen.

Din sista rubrikfil ska se ut som bilden 7.1. Din singletons associerade CPP -fil ska se ut som Foto 6.2 med tillägg av, högst upp i filen, av koden som visas i steg 8. Denna instruktion gav dig en enkel struktur för Singleton Design Pattern.

Råd om felsökning:

Får minnesrelaterade fel?

Se till att du hänvisar till steg 7 och steg 8 för att se till att du ställer in ptrInstance på nullptr.

Oändlig slinga som inträffar?

Se till att de offentliga funktionerna, i deras definitioner, kallar den privata funktionen, inte samma offentliga funktion.

Objekt tilldelade inom singleton som orsakar minnesläckage?

Se till att du ringer din singletons avslutningsfunktion när det är lämpligt inom din programkod, och i destruktorn för din singleton, se till att du avdelar alla objekt som har tilldelats minne inom ramen för singletonkoden.