====== Návrhové vzory - singleton ======= Nejspíšě nejjednodušším návrhovým vzorem je singleton, třída která může existovat jen v jedné instanci. Některé knihovny používají singleton pro získání globální konfigurace, kterou nechtějí ukládat do globální proměnné. [[https://doc.qt.io/qt-5/qcoreapplication.html#instance|QApplication::instace()]] Vytvoříme třídu //Singleton//, která v našem případě bude skladovat jen jedno číslo a \\ poskytne uživateli metody **getNumber** a **setNumber**. class Singleton { private: int number; public: int getNumber () { return number; } void setNumber (int n) { number = n; } //Konstruktor// bude //privátní//, aby nebylo možné vytvářet další instance. private: Singleton (); Jedinou instanci vytvoří //statická// metoda **getInstance**, která je uvnitř naší třídy a může zavolat privátní konstruktor. \\ Výsledkem metody bude odkaz (reference) na zmíněnou jedinou instanci public: static Singleton & getInstance (); Veřejnou statickou metodu můžeme zavolat i mimo naší třídu int main () { Singleton & p = Singleton::getInstance (); p.setNumber (7); } Vytvořit novou instanci nelze, překladač ohlásí chybu int main () { Singleton s; // ERROR: constructor is private } Ukazatel na instanci před uživatelem schováme do privátní proměnné **obj**. \\ Proměnná bude statická, bude tedy existovat pouze jedna, podobně jako globální proměnné. \\ Ke statické proměnné má přístup statická metoda //getInstance// private: static Singleton * obj; Statickou proměnnou musíme ještě definovat a současně ji přiřadíme nulovou počáteční hodnotu. \\ ( Definice je podobná implementaci metod. ) Singleton * Singleton::obj = NULL; //Statická// metoda //getInstance// je uvniř třídy //Singleton// a tedy může vytvořit novou instanci, \\ zavolat privátní konstruktor a \\ vrátit jako svůj výsledek odkaz na instanci. Singleton & Singleton::getInstance () { if (obj == NULL) obj = new Singleton (); return *obj; } ===== Deklarace třídy v hlavičkovém souboru ===== class Singleton { private: int number; public: int getNumber () { return number; } void setNumber (int n) { number = n; } private: Singleton (); private: static Singleton * obj; public: static Singleton & getInstance (); }; ===== Definice statické proměnné a definice jednotlivých metod ===== Singleton * Singleton::obj = NULL; Singleton::Singleton() { number = 0; } Singleton & Singleton::getInstance () { if (obj == NULL) obj = new Singleton (); return *obj; } ===== Funkce main ===== int main () { Singleton & p = Singleton::getInstance (); p.setNumber (7); // Singleton s; // constructor is private return 0; }