====== 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;
}