Πώς να δημιουργήσετε ένα Singleton σε C++

Pos Na Demiourgesete Ena Singleton Se C



Στην C++, ένα singleton είναι μια αρχή σχεδίασης που διασφαλίζει την παρουσία ενός μοναχικού στιγμιότυπου της τάξης σε όλο το πρόγραμμα και παρέχει ένα παγκόσμιο σημείο πρόσβασης σε αυτό το συγκεκριμένο παράδειγμα.

Το μοτίβο singleton χρησιμοποιείται συνήθως όταν χρειάζεται να έχετε έναν ενιαίο, κοινόχρηστο πόρο στον οποίο θα πρέπει να έχετε πρόσβαση παγκοσμίως, όπως μια σύνδεση βάσης δεδομένων, ένα καταγραφικό ή ένας διαχειριστής διαμόρφωσης. Με την επιβολή μιας μεμονωμένης παρουσίας, επιτρέπει σε πολλά μέρη του προγράμματος να έχουν πρόσβαση και να τροποποιούν το ίδιο αντικείμενο, προωθώντας τη συνέπεια των δεδομένων και μειώνοντας την ανάγκη για καθολικές μεταβλητές. Το Singleton μπορεί να χρησιμοποιηθεί ως προσωρινή μνήμη αντικειμένων όπου τα συχνά χρησιμοποιούμενα ή ακριβά στη δημιουργία αντικείμενα αποθηκεύονται και επαναχρησιμοποιούνται σε όλη την εφαρμογή. Αυτή η προσέγγιση βοηθά στη βελτίωση της απόδοσης αποφεύγοντας τη δημιουργία περιττών αντικειμένων και την αρχικοποίηση.

Σε αυτό το άρθρο, θα εξηγήσουμε τη δημιουργία ενός singleton και θα δείξουμε ένα παράδειγμα στυλιζαρίσματος ενός singleton σε ένα πρόγραμμα C++.







Παράδειγμα 1: Δημιουργία απλού Singleton με Eager Initialization

Ένα απλό singleton με πρώιμη αρχικοποίηση είναι ένα μοτίβο σχεδίασης που διασφαλίζει ότι δημιουργείται μόνο ένα στιγμιότυπο μιας κλάσης και δημιουργείται με ανυπομονησία κατά τη στατική προετοιμασία.



Θα δείξουμε το βασικό απόσπασμα κώδικα για τη δημιουργία ενός απλού singleton με αρχικοποίηση eager. Ας ξεκινήσουμε με το πρόγραμμα:



#include

τάξη Singleton {
ιδιωτικός :
στατικός Μοναδικό χαρτί * παράδειγμα ;
Μοναδικό χαρτί ( ) { }
δημόσιο :
στατικός Μοναδικό χαρτί * getInstance ( ) {
ΕΠΙΣΤΡΟΦΗ παράδειγμα ;
}
} ;


Μοναδικό χαρτί * Μοναδικό χαρτί :: παράδειγμα = νέο Σίνγκλετον ( ) ;

ενθ κύριος ( ) {

Μοναδικό χαρτί * singletonInstance1 = Μοναδικό χαρτί :: getInstance ( ) ;

Μοναδικό χαρτί * singletonInstance2 = Μοναδικό χαρτί :: getInstance ( ) ;

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

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

ΕΠΙΣΤΡΟΦΗ 0 ;

}

Ο κώδικας περιλαμβάνει την κεφαλίδα η οποία παρέχει τη λειτουργικότητα για εργασία με ροές εισόδου και εξόδου, όπως 'std::cout'.





Αφού συμπεριλάβουμε το αρχείο κεφαλίδας, ορίζουμε την κλάση 'Singleton' που αντιπροσωπεύει την υλοποίηση του μοτίβου singleton. Έχει έναν ιδιωτικό κατασκευαστή και μια μεταβλητή ιδιωτικού στατικού μέλους που ονομάζεται 'instance'.

Στη συνέχεια, η συνάρτηση getInstance() υλοποιείται ως δημόσια συνάρτηση στατικού μέλους της κλάσης 'Singleton'. Επιστρέφει το στιγμιότυπο του singleton που είναι αποθηκευμένο στο στιγμιότυπο της μεταβλητής στατικού μέλους. Το στιγμιότυπο της μεταβλητής στατικού μέλους ορίζεται και αρχικοποιείται εκτός της κλάσης με 'Singleton* Singleton::instance = new Singleton();'. Αυτή η γραμμή αρχικοποιεί το στιγμιότυπο της κλάσης 'Singleton' με ανυπομονησία κατά τη στατική προετοιμασία.



Στη συνάρτηση main(), δηλώνουμε δύο δείκτες, 'singletonInstance1' και 'singletonInstance2', και εκχωρούμε την τιμή που επιστρέφεται καλώντας το Singleton::getInstance(). Εφόσον το στιγμιότυπο προετοιμάζεται με ανυπομονησία, και οι δύο δείκτες δείχνουν την ίδια παρουσία. Οι δηλώσεις 'std::cout' εκτυπώνουν τις διευθύνσεις μνήμης των 'singletonInstance1' και 'singletonInstance2' στην κονσόλα χρησιμοποιώντας τον τελεστή '<<' και 'std::endl'.

Ο κωδικός τελειώνει με ένα 'return 0' που υποδεικνύει μια επιτυχημένη εκτέλεση του προγράμματος.

Όταν εκτελείτε αυτόν τον κώδικα, η έξοδος είναι κάπως έτσι:

Η έξοδος εμφανίζει τις διευθύνσεις μνήμης των 'singletonInstance1' και 'singletonInstance2'. Εφόσον και οι δύο δείκτες έχουν εκχωρηθεί με την ίδια παρουσία που λαμβάνονται από το Singleton::getInstance(), έχουν την ίδια διεύθυνση μνήμης. Αυτό δείχνει πώς το μοτίβο singleton εγγυάται ότι υπάρχει ένα μόνο στιγμιότυπο της κλάσης και ότι οι μελλοντικές κλήσεις στη getInstance() καταλήγουν πάντα στην ίδια παρουσία.

Παράδειγμα 2: Εφαρμογή μοτίβου Singleton με Lazy Initialization

Αυτή η επίδειξη εξηγεί την υλοποίηση του προτύπου singleton με lazy αρχικοποίηση και δείχνει τη χρήση του στη συνάρτηση main(). Η εξήγηση βήμα προς βήμα του αποσπάσματος κώδικα παρέχεται μετά από αυτό το πρόγραμμα:

#include

τάξη Singleton {

ιδιωτικός :

στατικός Μοναδικό χαρτί * παράδειγμα ;

Μοναδικό χαρτί ( ) {

std :: cout << 'Η παρουσία του Singleton δημιουργήθηκε.' << std :: endl ;

}

δημόσιο :

στατικός Μοναδικό χαρτί * getInstance ( ) {

αν ( παράδειγμα == nullptr ) {

παράδειγμα = νέο Σίνγκλετον ( ) ;

}

ΕΠΙΣΤΡΟΦΗ παράδειγμα ;

}

κενός showMessage ( ) {

std :: cout << 'Γεια σου από τον Σίνγκλετον!' << std :: endl ;

}

~ Σίνγκλετον ( ) {

std :: cout << 'Η περίπτωση του Singleton καταστράφηκε.' << std :: endl ;

}

} ;

Μοναδικό χαρτί * Μοναδικό χαρτί :: παράδειγμα = nullptr ;

ενθ κύριος ( ) {

Μοναδικό χαρτί * singletonInstance1 = Μοναδικό χαρτί :: getInstance ( ) ;

singletonInstance1 -> showMessage ( ) ;

Μοναδικό χαρτί * singletonInstance2 = Μοναδικό χαρτί :: getInstance ( ) ;

singletonInstance2 -> showMessage ( ) ;

ΕΠΙΣΤΡΟΦΗ 0 ;

}

Το πρόγραμμα ξεκινά προσθέτοντας το αρχείο κεφαλίδας για την εκτέλεση των εργασιών εισόδου/εξόδου. Στη συνέχεια, δηλώνουμε και ορίζουμε μια κλάση 'Singleton'. Το μοναδικό στιγμιότυπο της κλάσης διατηρείται εντός της μεταβλητής ιδιωτικού στατικού μέλους που ονομάζεται 'instance'.

Κάθε φορά που καλείται ο κατασκευαστής της κλάσης 'Singleton', δημιουργεί ένα στιγμιότυπο της κλάσης 'Singleton'. Εξάγει το μήνυμα 'Singleton instance δημιουργήθηκε' στην κονσόλα χρησιμοποιώντας το 'std::cout << … << std::endl;'. Ο κατασκευαστής δεν έχει παραμέτρους καθώς είναι προεπιλεγμένος κατασκευαστής. Ορίζεται ως Singleton() χωρίς κανένα όρισμα. Το δηλώνουμε ως ιδιωτικό που σημαίνει ότι μπορεί να γίνει επίκληση μόνο από το εσωτερικό της τάξης. Αυτό αποτρέπει μια άμεση εγκατάσταση της κλάσης 'Singleton' και διασφαλίζει ότι ο μόνος τρόπος για να αποκτήσετε ένα στιγμιότυπο είναι μέσω της συνάρτησης getInstance().

Η μέθοδος getInstance() της κλάσης 'Singleton' δηλώνεται ως δημόσια στατική συνάρτηση μέλους. Είναι στο ρόλο της καθιέρωσης και της παροχής προσβασιμότητας στο singleton instance. Μέσα στο getInstance(), ελέγχει αν το στιγμιότυπο είναι 'nullptr'. Εάν είναι, υποδηλώνοντας ότι η παρουσία δεν είναι ήδη παρούσα, χρησιμοποιεί τον ιδιωτικό κατασκευαστή για να δημιουργήσει ένα νέο αντικείμενο της κλάσης 'Singleton'.

Η συνάρτηση showMessage() είναι μια απλή συνάρτηση μέλους που εμφανίζει το 'Hello from Singleton!' μήνυμα. Ορίζεται ο καταστροφέας του singleton. Ονομάζεται σιωπηρά όταν το πρόγραμμα τερματίζει και εκτυπώνει το 'στιγμιότυπο Singleton καταστράφηκε'. μήνυμα που υποδεικνύει ότι η παρουσία του singleton έχει καταστραφεί. Το στιγμιότυπο της μεταβλητής στατικού μέλους ορίζεται αρχικά ως 'nullptr'.

Η int main() ξεκινά τον ορισμό της συνάρτησης main(). Στη συνέχεια, το 'Singleton* singletonInstance1 = Singleton::getInstance();' καλεί τη συνάρτηση getInstance() της κλάσης 'Singleton' για να αποκτήσει έναν δείκτη στην παρουσία singleton. Εκχωρεί αυτόν τον δείκτη στη μεταβλητή 'singletonInstance1'.

Μετά από αυτό, το 'singletonInstance1->showMessage();' χρησιμοποιεί τον τελεστή βέλους (->) για να καλέσει τη συνάρτηση showMessage() στον δείκτη 'singletonInstance1'. Αυτή η λειτουργία εμφανίζει το μήνυμα που καθορίζεται σε αυτήν στην κονσόλα. Στη συνέχεια, το 'Singleton* singletonInstance2 = Singleton::getInstance();' καλεί ξανά τη συνάρτηση getInstance(), λαμβάνοντας έναν άλλο δείκτη στην παρουσία singleton. Αυτή τη φορά, εκχωρεί το δείκτη στη μεταβλητή 'singletonInstance2'. Το 'singletonInstance2->showMessage();' καλεί τη συνάρτηση showMessage() στον δείκτη 'singletonInstance2'. Αυτή η λειτουργία εμφανίζει το 'Hello from Singleton!' μήνυμα ξανά στην κονσόλα.

Τέλος, 'επιστροφή 0;' δηλώνει το τέλος της συνάρτησης main() και το πρόγραμμα επιστρέφει την τιμή 0 που σημαίνει επιτυχημένη εκτέλεση του προγράμματος.

Ακολουθεί η έξοδος του αποσπάσματος κώδικα που εξηγήθηκε προηγουμένως:

Αυτό το αποτέλεσμα επιβεβαιώνει ότι η κλάση 'Singleton' διασφαλίζει τη δημιουργία μόνο μιας παρουσίας και ότι περαιτέρω κλήσεις στη συνάρτηση getInstance() αποδίδουν αξιόπιστα την ίδια παρουσία.

συμπέρασμα

Η δημιουργία ενός singleton σε C++ είναι μια πολύ χρήσιμη ιδέα. Σε αυτήν την ανάρτηση, αρχικά καλύψαμε την ενότητα εισαγωγής του singleton. Επιπλέον, παράγονται δύο παραδείγματα για την υλοποίηση του singleton στη C++. Η πρώτη εικόνα δείχνει την υλοποίηση της αρχικοποίησης eager singleton. Ενώ η εφαρμογή lazy αρχικοποίησης του μοτίβου singleton παρέχεται στο δεύτερο παράδειγμα αυτού του άρθρου. Επιπλέον, τα στιγμιότυπα της παραγόμενης εξόδου εμφανίζονται και για τα αντίστοιχα προγράμματα.