Cum se creează un singleton în C++

Cum Se Creeaza Un Singleton In C



În C++, un singleton este un principiu de proiectare care asigură prezența unei instanțe solitare a clasei pe tot parcursul programului și oferă un punct de acces global la acea instanță particulară.

Modelul singleton este folosit în mod obișnuit atunci când trebuie să aveți o resursă unică, partajată, care ar trebui accesată la nivel global, cum ar fi o conexiune la bază de date, un logger sau un manager de configurare. Prin aplicarea unei singure instanțe, permite mai multor părți ale programului să acceseze și să modifice același obiect, promovând consistența datelor și reducând nevoia de variabile globale. Singleton poate fi folosit ca cache de obiecte unde obiectele utilizate frecvent sau care sunt scumpe de creat sunt stocate și reutilizate în întreaga aplicație. Această abordare ajută la îmbunătățirea performanței prin evitarea creării și inițializării obiectelor redundante.

În acest articol, vom explica crearea unui singleton și vom demonstra un exemplu de stilizare a unui singleton într-un program C++.







Exemplul 1: Crearea unui singleton simplu cu inițializare dornică

Un singleton simplu cu inițializare timpurie este un model de proiectare care asigură că este creată o singură instanță a unei clase și este creată cu nerăbdare în timpul inițializării statice.



Vom demonstra fragmentul de cod de bază pentru crearea unui singleton simplu cu inițializare dornică. Să începem cu programul:



#include

clasa Singleton {
privat :
static Singleton * instanță ;
Singleton ( ) { }
public :
static Singleton * getInstance ( ) {
întoarcere instanță ;
}
} ;


Singleton * Singleton :: instanță = noul Singleton ( ) ;

int principal ( ) {

Singleton * singletonInstance1 = Singleton :: getInstance ( ) ;

Singleton * singletonInstance2 = Singleton :: getInstance ( ) ;

std :: cout << 'singletonletonInstance1: ' << singletonInstance1 << std :: endl ;

std :: cout << 'singletonletonInstance2: ' << singletonInstance2 << std :: endl ;

întoarcere 0 ;

}

Codul include antetul care oferă funcționalitatea de a lucra cu fluxuri de intrare și de ieșire, cum ar fi „std::cout”.





După includerea fișierului antet, definim clasa „Singleton” care reprezintă implementarea modelului singleton. Are un constructor privat și o variabilă membru static privat numită „instanță”.

Apoi, funcția getInstance() este implementată ca o funcție publică membru statică a clasei „Singleton”. Returnează instanța singleton-ului care este stocată în instanța variabilei membru statice. Instanța variabilei membru static este definită și inițializată în afara clasei cu „Singleton* Singleton::instance = new Singleton();”. Această linie inițializează instanța clasei „Singleton” cu nerăbdare în timpul inițializării statice.



În funcția main(), declarăm doi pointeri, „singletonInstance1” și „singletonInstance2”, și atribuim valoarea care este returnată prin apelarea Singleton::getInstance(). Deoarece instanța este inițializată cu nerăbdare, ambii pointeri indică aceeași instanță. Instrucțiunile „std::cout” imprimă adresele de memorie ale „singletonInstance1” și „singletonInstance2” pe consolă folosind operatorul „<<” și „std::endl”.

Codul se termină cu un „return 0” care indică o execuție reușită a programului.

Când rulați acest cod, rezultatul este cam așa:

Ieșirea afișează adresele de memorie ale „singletonInstance1” și „singletonInstance2”. Deoarece ambii pointeri sunt alocați cu aceeași instanță obținută de la Singleton::getInstance(), ei au aceeași adresă de memorie. Acest lucru demonstrează cum modelul singleton garantează că există o singură instanță a clasei și că apelurile viitoare la getInstance() au ca rezultat întotdeauna aceeași instanță.

Exemplul 2: Implementarea modelului Singleton cu Inițializare Lenenă

Această demonstrație explică implementarea modelului singleton cu inițializare leneșă și arată utilizarea acestuia în funcția main(). Explicația pas cu pas a fragmentului de cod este oferită după acest program:

#include

clasa Singleton {

privat :

static Singleton * instanță ;

Singleton ( ) {

std :: cout << „Instanță singleton creată”. << std :: endl ;

}

public :

static Singleton * getInstance ( ) {

dacă ( instanță == nullptr ) {

instanță = noul Singleton ( ) ;

}

întoarcere instanță ;

}

gol showMessage ( ) {

std :: cout << 'Bună ziua de la Singleton!' << std :: endl ;

}

~Singleton ( ) {

std :: cout << „Instanță unică a fost distrusă”. << std :: endl ;

}

} ;

Singleton * Singleton :: instanță = nullptr ;

int principal ( ) {

Singleton * singletonInstance1 = Singleton :: getInstance ( ) ;

singletonInstance1 -> showMessage ( ) ;

Singleton * singletonInstance2 = Singleton :: getInstance ( ) ;

singletonInstance2 -> showMessage ( ) ;

întoarcere 0 ;

}

Programul începe prin adăugarea fișierului antet pentru a efectua sarcinile de intrare/ieșire. Apoi, declarăm și definim o clasă „Singleton”. Singura instanță a clasei este păstrată în variabila membru static privat numită „instanță”.

Ori de câte ori este apelat constructorul clasei „Singleton”, acesta generează o instanță a clasei „Singleton”. Acesta trimite mesajul „Singleton instance created” către consolă folosind „std::cout << … << std::endl;”. Constructorul nu are niciun parametru deoarece este un constructor implicit. Este definit ca Singleton() fără niciun argument. Îl declarăm ca privat, ceea ce înseamnă că poate fi invocat doar din interiorul clasei. Acest lucru previne o instanțiere directă a clasei „Singleton” și asigură că singura modalitate de a obține o instanță este prin funcția getInstance().

Metoda getInstance() a clasei „Singleton” este declarată ca o funcție publică membru statică. Are rolul de a stabili și de a acorda accesibilitate instanței singleton. În interiorul getInstance(), verifică dacă instanța este „nullptr”. Dacă este, ceea ce înseamnă că instanța nu este deja prezentă, folosește constructorul privat pentru a instanția un nou obiect al clasei „Singleton”.

Funcția showMessage() este o funcție simplă de membru care afișează „Hello from Singleton!” mesaj. Destructorul singleton este definit. Este apelat implicit atunci când programul se termină și tipărește „Instanța Singleton distrusă”. mesaj care indică faptul că instanța singleton este distrusă. Instanța variabilei membru static este definită inițial ca „nullptr”.

int main() începe definirea funcției main(). Apoi, „Singleton* singletonInstance1 = Singleton::getInstance();” apelează funcția getInstance() a clasei „Singleton” pentru a obține un pointer către instanța singleton. Acesta atribuie acest indicator variabilei „singletonInstance1”.

După aceea, „singletonInstance1->showMessage();” folosește operatorul săgeată (->) pentru a apela funcția showMessage() pe pointerul „singletonInstance1”. Această funcție afișează pe consolă mesajul care este specificat în ea. După aceea, „Singleton* singletonInstance2 = Singleton::getInstance();” apelează din nou funcția getInstance(), obținând un alt pointer către instanța singleton. De data aceasta, atribuie indicatorul variabilei „singletonInstance2”. „singletonInstance2->showMessage();” apelează funcția showMessage() de pe pointerul „singletonInstance2”. Această funcție afișează „Salut de la Singleton!” mesaj din nou către consolă.

În sfârșit, „return 0;” semnifică sfârșitul funcției main(), iar programul returnează valoarea 0, ceea ce înseamnă o execuție cu succes a programului.

Iată rezultatul fragmentului de cod explicat anterior:

Acest rezultat confirmă faptul că clasa „Singleton” asigură crearea unei singure instanțe și că apelurile ulterioare la funcția getInstance() produc în mod fiabil aceeași instanță.

Concluzie

Crearea unui singleton în C++ este un concept foarte util. În această postare, am acoperit inițial secțiunea de introducere a singleton. Mai mult, două exemple sunt produse pentru a implementa singleton-ul în C++. Prima ilustrație arată implementarea inițializării singleton dornice. În timp ce implementarea inițializării leneșe a modelului singleton este furnizată în al doilea exemplu al acestui articol. Mai mult, instantaneele rezultatelor produse sunt afișate și pentru programele corespunzătoare.