Cuprins:
- Pasul 1: Creați-vă cursul, cu fișier antet și fișier CPP
- Pasul 2: setați Constructorul la Privat
- Pasul 3: setați Distructorul la Privat
- Pasul 4: Crearea unei variabile de pointer static în Singleton
- Pasul 5: Crearea unei funcții de instanță
- Pasul 6: Crearea funcțiilor publice statice
- Pasul 7: Crearea funcției Terminare
- Pasul 8: Setarea PtrInstance la Nullptr
- Pasul 9: Test și concluzie
Video: Cum se face modelul de proiectare Singleton în C ++: 9 pași
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:44
Introducere:
Scopul acestui ghid de instrucțiuni este de a învăța utilizatorul despre cum să implementeze modelul de proiectare singleton în programul lor C ++. Procedând astfel, acest set de instrucțiuni va explica, de asemenea, cititorului de ce elementele unui singleton sunt așa cum sunt și cum este procesat codul. Știind acest lucru, vă va ajuta în viitor la depanarea viitorilor dvs. singletoni. Care este modelul de design Singleton? Modelul de proiectare singleton este un model de proiectare în care coderul creează o clasă care poate fi instanțiată o singură dată, funcțiile publice ale claselor pot fi practic accesate oriunde, cu condiția să fi inclus # fișierul antet în alte fișiere legate de proiect.
Modelul de proiectare singleton este un model de design obligatoriu pentru orice programator orientat pe obiecte, programatori software și programatori de jocuri. Modelul de design singleton este, de asemenea, unul dintre cele mai ușoare modele de proiectare a codificării. Învățarea acestuia vă poate ajuta să învățați alte modele de proiectare mai dificile în viitor. De asemenea, vă poate ajuta să simplificați codul programului dvs. în moduri pe care nu le credeați posibile.
În timp ce dificultatea modelului de proiectare singleton este ușoară în comparație cu alte modele de proiectare, acest set de instrucțiuni are o dificultate medie. Aceasta înseamnă că, pentru a efectua aceste instrucțiuni, vă recomandăm să cunoașteți cerințele de sintaxă de bază și avansate ale C ++. De asemenea, ar trebui să cunoașteți eticheta corectă de codare C ++ (de exemplu, păstrați variabilele de clasă private, o clasă pentru fișierul de antet etc.). De asemenea, ar trebui să știți cum să eliberați memoria și cum funcționează constructorii și distructorii în C ++.
Acest ghid instructiv va dura în medie în jur de 10-15 minute.
Cerințe materiale:
-Un computer (poate fi PC sau Mac) capabil să ruleze Visual Studios (orice versiune)
-Un program simplu, creat în Visual Studios, cu care îți poți testa singletonul
Notă: modelul de proiectare singleton poate fi realizat pe orice altă interfață de codare sau IDE care acceptă C ++, dar pentru acest set de instrucțiuni vom folosi Visual Studios Enterprise Edition.
Pasul 1: Creați-vă cursul, cu fișier antet și fișier CPP
Pentru a crea aceste două fișiere și clasa dintr-o dată, deschideți proiectul / programul în Visual Studios, mergeți la exploratorul de soluții, faceți clic dreapta și o casetă ar trebui să apară lângă cursorul mouse-ului, găsiți opțiunea „Adăugați”, plasați cursorul deasupra acestuia și o altă casetă ar trebui să apară în dreapta. În această casetă, doriți să găsiți opțiunea „Element nou..”, faceți clic pe ea și ar trebui să apară o fereastră, asemănătoare cu imaginea foto 1.1 de mai jos. În această fereastră doriți să selectați „Clasa C ++” și apoi apăsați „Adăugați”. Astfel se va deschide o altă fereastră care seamănă cu imaginea foto 1.2. În această fereastră, introduceți numele clasei dvs. în câmpul „Nume clasă”, iar Visual Studios va denumi automat fișierul real după numele clasei. În scopul acestei instrucțiuni, vom denumi clasa noastră „EngineDebugSingleton”, dar poate fi orice nume bazat pe litere. Acum puteți apăsa „OK” și continuați cu pasul 2.
Notă: Exploratorul de soluții și locul în care sunt păstrate fișierele pe computer sunt separate. Mutarea sau crearea a ceva în exploratorul de soluții nu va muta sau organiza fișierele din exploratorul de fișiere al sistemului de operare. O modalitate sigură de a vă organiza fișierele din partea exploratorului de fișiere ar fi eliminarea, dar nu ștergerea fișierelor specifice din exploratorul de soluții, mutați aceleași fișiere în exploratorul de fișiere în locația dorită și apoi reveniți la soluția de explorare, faceți clic dreapta, găsiți opțiunea „Adăugați”, apoi găsiți „Element existent” și găsiți fișierele pe care le-ați mutat. Asigurați-vă că mutați atât antetul, cât și fișierul CPP.
Pasul 2: setați Constructorul la Privat
Cu noul fișier CPP și fișierul antet, dacă nu s-a deschis automat când l-ați creat, accesați soluția de explorare și faceți clic și deschideți „EngineDebugSingleton.h”. Apoi veți fi întâmpinat cu un „EngineDebugSingleton ()”, constructorul implicit al clasei și „~ EngineDebugSingleton ()” distructorul clasei. Pentru acest pas, vom dori să setăm constructorul la privat, aceasta înseamnă că această funcție este disponibilă doar pentru clasă și nimic altceva. Cu aceasta, nu veți putea crea o variabilă sau să alocați clasa în memoria din afara clasei, numai în fișierul antet al claselor și în celelalte funcții ale claselor. A avea constructorul privat este cheia modelului de proiectare și a modului în care operează singletonii. În viitorii pași vom descoperi cum este instanțiat și accesat un single.
Clasa ar trebui să arate acum după ce mută constructorul în privat (Uită-te la fotografia asociată)
Pasul 3: setați Distructorul la Privat
Așa cum am făcut cu constructorul din
pasul 2, pentru acest pas, vom seta acum distructorul la privat. Ca și în cazul constructorului, nimic, cu excepția clasei în sine, nu va putea șterge din memorie orice variabile ale clasei.
Clasa ar trebui să arate acum după finalizarea acestui pas. (Vezi fotografia asociată)
Pasul 4: Crearea unei variabile de pointer static în Singleton
În acest pas, vom crea un
variabilă statică a indicatorului de tip „EngineDebugSingleton *”. Aceasta va fi variabila care va fi utilizată pentru a aloca singletonul nostru în memorie și îl va indica pentru tot timpul cât singletonul nostru este alocat în memorie.
Așa ar trebui să arate fișierul nostru de antet după crearea acestei variabile
Pasul 5: Crearea unei funcții de instanță
Acum vrem să facem o instanță
funcţie. Funcția va trebui să fie o funcție statică și va dori să returneze o referință la clasa noastră („EngineDebugSingleton &”). Am numit funcția noastră Instanță (). În funcția în sine, vom dori să testăm mai întâi dacă ptrInstance == nullptr (poate fi scurtat la! PtrInstance), dacă este nullptr, aceasta înseamnă că singletonul nu a fost alocat și în sfera instrucțiunii if, vom doriți să alocați făcând ptrInstance = new EngineDebugSingleton (). Aici alocați singletonul în memorie. După ce ieșim din sfera instrucțiunii if, vom returna spre ce indică ptrInstance, care este notată de sintaxa „* ptrInstance”. Vom folosi această funcție foarte mult atunci când ne facem funcțiile publice statice, astfel încât să putem verifica dacă singletonul a fost creat și alocat în memorie. În esență, această funcție o face astfel încât să puteți avea o singură alocare a clasei și nu mai mult.
Așa ar trebui să arate clasa noastră acum după crearea funcției Instance (). După cum puteți vedea, tot ceea ce am făcut a rămas în secțiunea privată a clasei, acest lucru urmând să se schimbe puțin în următorii pași.
Pasul 6: Crearea funcțiilor publice statice
După ce ați realizat funcția din
pasul 5, puteți începe să creați funcții publice statice. Fiecare funcție publică ar trebui să aibă o funcție privată pentru a merge împreună cu ea, numele acestei funcții nu poate fi același. De ce să faceți funcția statică? Facem funcțiile publice statice, astfel încât să poată fi accesate fără un obiect real. Deci, în loc să facem ceva de genul „EngineDebugSingleObj-> SomeFunction ()”, facem „EngineDebugSingleton:: Some Function ()”. Acest lucru face posibil ca un singleton să fie accesat practic oriunde în cod, cu condiția să fi inclus # fișierul antet în fișierul de proiect specific cu care lucrați. Cu aceasta, puteți crea singletonul prin oricare dintre funcțiile sale publice.
În scopurile noastre, în acest pas, am creat două funcții de statice publice, „add ()” și „subtract ()”. În secțiunea privată, mai avem două funcții, „PrivAdd ()” și „PrivSubtract ()”. De asemenea, am adăugat o variabilă int numită „NumberOfThings”. Definiția pentru aceste funcții va intra în fișierul CPP al cursurilor noastre. Pentru a face cu ușurință funcția să intre în fișierul CPP, evidențiați, cu cursorul, funcția, care ar trebui să aibă o linie verde sub ea, și apăsați „ALT stânga + ENTER”, vă va oferi opțiunea de a crea definiția în fișierul CPP asociat claselor. Consultați fotografia 6.1 pentru a vedea cum ar trebui să arate fișierul antet și după ce ați creat toate definițiile funcției, CPP-ul dvs. ar trebui să arate ca fotografia 6.2, cu excepția faptului că definițiile funcției dvs. nu vor avea cod în ele.
Acum veți dori să adăugați același cod ca în fotografia 6.2 în definițiile funcției. După cum sa menționat anterior, funcțiile noastre publice vor folosi funcția Instance (), care va returna ceea ce indică ptrInstance. Acest lucru ne permite să accesăm funcțiile private ale clasei noastre. Cu funcția publică a oricărui singleton, ar trebui să apelați acea funcție de instanță. Singura excepție de la aceasta este funcția noastră Terminare.
Notă: funcțiile publice și private exacte afișate în acest pas nu sunt necesare, puteți avea nume și operații diferite în funcția privată, dar pentru orice tip de funcție publică, ar trebui să aveți o funcție privată care să o urmeze și funcția publică ar trebui să utilizeze întotdeauna, în cazul nostru, funcția Instance ().
Pasul 7: Crearea funcției Terminare
Deoarece putem clasifica singletonul nostru din memorie doar în clasa noastră, trebuie să creăm o funcție publică statică. Această funcție va apela ștergere pe ptrInstance, care apelează distructorul clasei și apoi vom dori să setăm ptrInstance înapoi la nullptr, astfel încât să poată fi alocat din nou dacă programul dvs. nu se termină. De asemenea, veți dori să vă terminați Singletonii pentru a curăța orice memorie alocată pe care ați alocat-o în variabilele private ale oricărui Singleton.
Pasul 8: Setarea PtrInstance la Nullptr
Pentru a vă completa singletonul, doriți să accesați fișierul EngineDebugSingleton. CPP și în partea de sus a fișierului CPP, tastați „EngineDebugSingleton * EngineDebugSingleton:: ptrInstance = nullptr”.
Dacă faceți acest lucru, ptrInstance va fi setat inițial la nullptr, așa că atunci când treceți prima dată prin funcția instanță, clasa noastră va fi alocată memoriei. Fără ea, cel mai probabil veți primi o eroare, deoarece veți încerca să accesați memoria care nu are nimic alocat ei.
Pasul 9: Test și concluzie
Acum vom dori să testăm dacă singletonul nostru pentru a ne asigura că funcționează, acest lucru ne va implica să apelăm funcțiile publice, așa cum este descris în pasul 6 și vă recomandăm să configurați puncte de întrerupere pentru a trece prin codul dvs. și să vedeți că singletonul funcționează ca ar trebui să fie. Punctul nostru de plecare va fi în main.cpp al proiectului nostru, iar main.cpp arăta acum ca imaginea de mai jos.
Felicitări! Tocmai ați finalizat prima dvs. implementare a modelului de design Singleton. Cu acest model de proiectare, puteți acum să vă simplificați codul într-o varietate de moduri. De exemplu, acum puteți crea sisteme de gestionare care funcționează pe durata programului dvs., care pot fi accesate prin funcții statice oriunde ați inclus clasa.
Fișierul de antet final ar trebui să arate ca fotografia 7.1. Fișierul CPP asociat singletonului dvs. ar trebui să arate ca fotografia 6.2 cu adăugarea, în partea de sus a fișierului, a codului prezentat la pasul 8. Această instrucțiune vă oferă o structură simplă a modelului de design Singleton.
Sfaturi pentru depanare:
Obțineți erori legate de memorie?
Asigurați-vă că consultați pasul 7 și pasul 8 pentru a vă asigura că setați ptrInstance la nullptr.
Se produce o buclă infinită?
Asigurați-vă că pentru funcțiile publice, în definițiile lor, numiți funcția privată, nu aceeași funcție publică.
Obiectele alocate în cadrul singletonului cauzează scurgeri de memorie?
Asigurați-vă că apelați funcția de terminare a singletonului atunci când este adecvat în cadrul codului de program și, în destructorul singletonului, asigurați-vă că alocați orice obiecte care au fost alocate memoriei în cadrul codului de singleton.