Esercizi Singleton Pattern C++
Ecco degli esercizi con soluzione per praticare l’utilizzo del Singleton Pattern in C++.
Esercizio 1: Implementazione base del Singleton Pattern
Creare una classe Singleton con un metodo statico per ottenere l'istanza unica.
#include <iostream>
class Singleton {private: static Singleton* instance; Singleton() {}
public: static Singleton* getInstance() { if (!instance) { instance = new Singleton(); } return instance; }
void printMessage() { std::cout << "Istanza Singleton" << std::endl; }};
Singleton* Singleton::instance = nullptr;
int main() { Singleton* s1 = Singleton::getInstance(); Singleton* s2 = Singleton::getInstance();
s1->printMessage();
std::cout << "s1 e s2 sono uguali: " << (s1 == s2) << std::endl; // Devono essere uguali
return 0;}
Esercizio 2: Singleton con mutex per thread safety
Modificare la classe Singleton per renderla thread-safe usando `std::mutex`.
#include <iostream>#include <mutex>
class Singleton {private: static Singleton* instance; static std::mutex mtx; Singleton() {}
public: static Singleton* getInstance() { std::lock_guard<std::mutex> lock(mtx); if (!instance) { instance = new Singleton(); } return instance; }
void printMessage() { std::cout << "Istanza Singleton" << std::endl; }};
Singleton* Singleton::instance = nullptr;std::mutex Singleton::mtx;
int main() { Singleton* s1 = Singleton::getInstance(); Singleton* s2 = Singleton::getInstance();
s1->printMessage();
std::cout << "s1 e s2 sono uguali: " << (s1 == s2) << std::endl; // Devono essere uguali
return 0;}
Esercizio 3: Singleton con blocco a doppio controllo
Implementare la classe Singleton usando il blocco a doppio controllo per migliorare l'efficienza del thread safety.
#include <iostream>#include <mutex>
class Singleton {private: static Singleton* instance; static std::mutex mtx; Singleton() {}
public: static Singleton* getInstance() { if (!instance) { std::lock_guard<std::mutex> lock(mtx); if (!instance) { instance = new Singleton(); } } return instance; }
void printMessage() { std::cout << "Istanza Singleton" << std::endl; }};
Singleton* Singleton::instance = nullptr;std::mutex Singleton::mtx;
int main() { Singleton* s1 = Singleton::getInstance(); Singleton* s2 = Singleton::getInstance();
s1->printMessage();
std::cout << "s1 e s2 sono uguali: " << (s1 == s2) << std::endl; // Devono essere uguali
return 0;}
Esercizio 4: Singleton con distruzione controllata
Implementare la classe Singleton con un distruttore controllato per gestire correttamente la distruzione dell'istanza.
#include <iostream>#include <mutex>
class Singleton {private: static Singleton* instance; static std::mutex mtx; Singleton() {} ~Singleton() { std::cout << "Distruttore Singleton chiamato" << std::endl; }
public: static Singleton* getInstance() { if (!instance) { std::lock_guard<std::mutex> lock(mtx); if (!instance) { instance = new Singleton(); std::atexit(destroyInstance); } } return instance; }
static void destroyInstance() { delete instance; instance = nullptr; }
void printMessage() { std::cout << "Istanza Singleton" << std::endl; }};
Singleton* Singleton::instance = nullptr;std::mutex Singleton::mtx;
int main() { Singleton* s1 = Singleton::getInstance(); Singleton* s2 = Singleton::getInstance();
s1->printMessage();
std::cout << "s1 e s2 sono uguali: " << (s1 == s2) << std::endl; // Devono essere uguali
return 0;}
Esercizio 5: Singleton utilizzando std::call_once
Implementare la classe Singleton utilizzando `std::call_once` per garantire l'inizializzazione sicura in ambienti multi-thread.
#include <iostream>#include <mutex>
class Singleton {private: static Singleton* instance; static std::once_flag initFlag; Singleton() {}
public: static Singleton* getInstance() { std::call_once(initFlag, []() { instance = new Singleton(); }); return instance; }
void printMessage() { std::cout << "Istanza Singleton" << std::endl; }};
Singleton* Singleton::instance = nullptr;std::once_flag Singleton::initFlag;
int main() { Singleton* s1 = Singleton::getInstance(); Singleton* s2 = Singleton::getInstance();
s1->printMessage();
std::cout << "s1 e s2 sono uguali: " << (s1 == s2) << std::endl; // Devono essere uguali
return 0;}
Esercizio 6: Singleton con smart pointer
Implementare la classe Singleton utilizzando `std::shared_ptr` per la gestione automatica della memoria.
#include <iostream>#include <memory>#include <mutex>
class Singleton {private: static std::shared_ptr<Singleton> instance; static std::mutex mtx; Singleton() {}
public: static std::shared_ptr<Singleton> getInstance() { std::lock_guard<std::mutex> lock(mtx); if (!instance) { instance = std::shared_ptr<Singleton>(new Singleton()); } return instance; }
void printMessage() { std::cout << "Istanza Singleton" << std::endl; }};
std::shared_ptr<Singleton> Singleton::instance = nullptr;std::mutex Singleton::mtx;
int main() { std::shared_ptr<Singleton> s1 = Singleton::getInstance(); std::shared_ptr<Singleton> s2 = Singleton::getInstance();
s1->printMessage();
std::cout << "s1 e s2 sono uguali: " << (s1 == s2) << std::endl; // Devono essere uguali
return 0;}