Come creare un singleton in C++

Come Creare Un Singleton In C



In C++, un singleton è un principio di progettazione che garantisce la presenza di un'istanza solitaria della classe in tutto il programma e fornisce un punto di accesso globale a quella particolare istanza.

Il modello singleton viene comunemente utilizzato quando è necessario disporre di un'unica risorsa condivisa a cui accedere a livello globale, ad esempio una connessione al database, un logger o un gestore di configurazione. Applicando una singola istanza, consente a più parti del programma di accedere e modificare lo stesso oggetto, promuovendo la coerenza dei dati e riducendo la necessità di variabili globali. Singleton può essere utilizzato come cache di oggetti in cui gli oggetti utilizzati di frequente o costosi da creare vengono archiviati e riutilizzati in tutta l'applicazione. Questo approccio aiuta a migliorare le prestazioni evitando la creazione e l'inizializzazione di oggetti ridondanti.

In questo articolo spiegheremo la creazione di un singleton e dimostreremo un esempio di stilizzazione di un singleton in un programma C++.







Esempio 1: creazione di un singleton semplice con inizializzazione desiderosa

Un singleton semplice con inizializzazione anticipata è un modello di progettazione che garantisce che venga creata una sola istanza di una classe e che venga creata con entusiasmo durante l'inizializzazione statica.



Dimostreremo il frammento di codice di base per la creazione di un semplice singleton con un'inizializzazione rapida. Cominciamo dal programma:



#include

classe Singleton {
privato :
statico Singleton * esempio ;
Singleton ( ) { }
pubblico :
statico Singleton * getInstance ( ) {
ritorno esempio ;
}
} ;


Singleton * Singleton :: esempio = nuovo Singletone ( ) ;

int principale ( ) {

Singleton * singletonInstance1 = Singleton :: getInstance ( ) ;

Singleton * singletonInstance2 = Singleton :: getInstance ( ) ;

standard :: cout << 'singletonletonIstanza1: ' << singletonInstance1 << standard :: fine ;

standard :: cout << 'singletonletonIstanza2: ' << singletonInstance2 << standard :: fine ;

ritorno 0 ;

}

Il codice include l'intestazione che fornisce la funzionalità per lavorare con flussi di input e output come 'std::cout'.





Dopo aver incluso il file header, definiamo la classe “Singleton” che rappresenta l'implementazione del pattern singleton. Ha un costruttore privato e una variabile membro statica privata denominata 'istanza'.

Quindi, la funzione getInstance() viene implementata come funzione membro statica pubblica della classe “Singleton”. Restituisce l'istanza del singleton archiviata nell'istanza della variabile membro statico. L'istanza della variabile del membro statico viene definita e inizializzata all'esterno della classe con 'Singleton* Singleton::instance = new Singleton();'. Questa riga inizializza con entusiasmo l'istanza della classe 'Singleton' durante l'inizializzazione statica.



Nella funzione main(), dichiariamo due puntatori, 'singletonInstance1' e 'singletonInstance2', e assegniamo il valore restituito chiamando Singleton::getInstance(). Poiché l'istanza viene inizializzata con entusiasmo, entrambi i puntatori puntano alla stessa istanza. Le istruzioni 'std::cout' stampano gli indirizzi di memoria di 'singletonInstance1' e 'singletonInstance2' sulla console utilizzando l'operatore '<<' e 'std::endl'.

Il codice termina con un 'ritorno 0' che indica l'esecuzione riuscita del programma.

Quando esegui questo codice, l'output è qualcosa del genere:

L'output visualizza gli indirizzi di memoria di 'singletonInstance1' e 'singletonInstance2'. Poiché a entrambi i puntatori viene assegnata la stessa istanza ottenuta da Singleton::getInstance(), hanno lo stesso indirizzo di memoria. Ciò dimostra come il modello singleton garantisca che esista una singola istanza della classe e che le future chiamate a getInstance() risultino sempre nella stessa istanza.

Esempio 2: implementazione del modello singleton con inizializzazione lazy

Questa dimostrazione spiega l'implementazione del modello singleton con l'inizializzazione lazy e ne mostra l'utilizzo nella funzione main(). La spiegazione passo passo dello snippet di codice viene fornita dopo questo programma:

#include

classe Singleton {

privato :

statico Singleton * esempio ;

Singleton ( ) {

standard :: cout << 'Istanza singleton creata.' << standard :: fine ;

}

pubblico :

statico Singleton * getInstance ( ) {

Se ( esempio == nullptr ) {

esempio = nuovo Singletone ( ) ;

}

ritorno esempio ;

}

vuoto showMessage ( ) {

standard :: cout << 'Ciao da Singleton!' << standard :: fine ;

}

~Singolo ( ) {

standard :: cout << 'Istanza singleton distrutta.' << standard :: fine ;

}

} ;

Singleton * Singleton :: esempio = nullptr ;

int principale ( ) {

Singleton * singletonInstance1 = Singleton :: getInstance ( ) ;

singletonInstance1 -> showMessage ( ) ;

Singleton * singletonInstance2 = Singleton :: getInstance ( ) ;

singletonInstance2 -> showMessage ( ) ;

ritorno 0 ;

}

Il programma inizia aggiungendo il file di intestazione per eseguire le attività di input/output. Quindi, dichiariamo e definiamo una classe “Singleton”. L'unica istanza della classe è mantenuta all'interno della variabile membro statica privata denominata 'istanza'.

Ogni volta che viene chiamato il costruttore della classe 'Singleton', genera un'istanza della classe 'Singleton'. Invia il messaggio 'Istanza Singleton creata' alla console utilizzando 'std::cout << ... << std::endl;'. Il costruttore non ha parametri poiché è un costruttore predefinito. È definito come Singleton() senza argomenti. Lo dichiariamo privato, il che significa che può essere invocato solo dall'interno della classe. Ciò impedisce un'istanziazione diretta della classe “Singleton” e garantisce che l'unico modo per ottenere un'istanza sia tramite la funzione getInstance().

Il metodo getInstance() della classe “Singleton” è dichiarato come funzione membro statica pubblica. Ha il ruolo di stabilire e garantire l'accessibilità all'istanza singleton. All'interno di getInstance(), controlla se l'istanza è 'nullptr'. Se lo è, a significare che l'istanza non è già presente, utilizza il costruttore privato per istanziare un nuovo oggetto della classe “Singleton”.

La funzione showMessage() è una semplice funzione membro che visualizza il messaggio 'Hello from Singleton!' Messaggio. Viene definito il distruttore di singleton. Viene chiamato implicitamente quando il programma termina e stampa 'Istanza Singleton distrutta'. messaggio che indica che l'istanza singleton è stata distrutta. L'istanza della variabile membro statica è inizialmente definita come 'nullptr'.

L'int main() avvia la definizione della funzione main(). Quindi, 'Singleton* singletonInstance1 = Singleton::getInstance();' chiama la funzione getInstance() della classe “Singleton” per ottenere un puntatore all'istanza singleton. Assegna questo puntatore alla variabile 'singletonInstance1'.

Successivamente, 'singletonInstance1->showMessage();' utilizza l'operatore freccia (->) per chiamare la funzione showMessage() sul puntatore 'singletonInstance1'. Questa funzione visualizza sulla console il messaggio in essa specificato. Successivamente, 'Singleton* singletonInstance2 = Singleton::getInstance();' chiama nuovamente la funzione getInstance(), ottenendo un altro puntatore all'istanza singleton. Questa volta assegna il puntatore alla variabile 'singletonInstance2'. Il 'singletonInstance2->showMessage();' chiama la funzione showMessage() sul puntatore 'singletonInstance2'. Questa funzione visualizza il messaggio 'Hello from Singleton!' messaggio nuovamente alla console.

Infine, 'return 0;' indica la fine della funzione main() e il programma restituisce il valore 0 che indica un'esecuzione corretta del programma.

Ecco l'output dello snippet di codice spiegato in precedenza:

Questo risultato conferma che la classe “Singleton” assicura la creazione di una sola istanza e che ulteriori chiamate alla funzione getInstance() restituiscono in modo affidabile la stessa istanza.

Conclusione

Creare un singleton in C++ è un concetto molto utile. In questo post abbiamo inizialmente trattato la sezione introduttiva di singleton. Inoltre, vengono prodotti due esempi per implementare il singleton in C++. La prima illustrazione mostra l'implementazione dell'inizializzazione del singleton desideroso. Mentre l'implementazione dell'inizializzazione pigra del modello singleton viene fornita nel secondo esempio di questo articolo. Inoltre per i programmi corrispondenti vengono visualizzate anche le istantanee dell'output prodotto.