[c++] Compile error se l'ordine di chiamata di due funzioni è invertito

di il
5 risposte

[c++] Compile error se l'ordine di chiamata di due funzioni è invertito

Salve a tutti,

Sto sviluppando un progetto in cui ho un singleton che deve deve però essere inizializzato mediante un metodo init prima che possa essere chiamata la funzione get_instance. Vorrei sapere se esiste un modo per controllare a compile time che la funzione init sia chiamata prima della chiamata di get_instance o se invece l'unico modo è usare un assert a runtime per controllare.

5 Risposte

  • Re: [c++] Compile error se l'ordine di chiamata di due funzioni è invertito

    A compile time no. Puoi usare la lazy initialization insieme a std::call_once per inizializzare una volta soltanto il singeton.
  • Re: [c++] Compile error se l'ordine di chiamata di due funzioni è invertito

    Immaginavo non si potesse, beh uso un semplice assert. Il problema non è far chiamare una sola volta l'inizializzatore quello può essere chiamato tutte le volte che si vuole ma voglio che l'init venga chiamato prima del get_instance. call_once non mi aiuterebbe.

    Grazie per la risposta
  • Re: [c++] Compile error se l'ordine di chiamata di due funzioni è invertito

    Ma come è fatto questo singleton? E' un template?
  • Re: [c++] Compile error se l'ordine di chiamata di due funzioni è invertito

    Scusa per la risposta tardiva. No il singleton è una "normale" classe non ha template. Il motivo per cui deve essere chiamato il metodo init prima di qualsiasi chiamata ad un istanza semplicemente per settare dei parametri di configurazione.
  • Re: [c++] Compile error se l'ordine di chiamata di due funzioni è invertito

    Non sapendo com'è fatto sto singleton ho azzardato questo. Da notare che la chiamata a Init() avviene una sola volta prima del main.
    (E' lo stesso sistema usato dalla libreria C++ per std::cout e std::cin)


    Singleton.h
    
    static struct SingInit {
    	SingInit();
    	~SingInit();
    	static int cnt;
    } singInit;
    
    class Singleton {
    	friend struct SingInit;
    	public:
    		static Singleton& instance() {
    			return sing2;
    		}
    	protected:
    		static void init();
    		static Singleton& sing2;
    };
    
    Singleton.cpp
    
    #include <iostream>
    #include <fstream>
    #include <new>
    #include <type_traits>
    #include "single.h"
    
    int SingInit::cnt;
    typename std::aligned_storage_t<sizeof(Singleton), alignof(Singleton)> SingStore;
    Singleton& Singleton::sing = reinterpret_cast<Singleton&>(SingStore);
    
    SingInit::SingInit() {
    	if (SingInit::cnt++ == 0) {
    		new (&Singleton::sing) Singleton();
    		Singleton::sing.init();
    	}
    }
    
    SingInit::~SingInit() {
    	if (--SingInit::cnt == 0)
    		(&Singleton::sing)->~Singleton();
    }
    
    void Singleton::init() {
    	std::ifstream ifs("file_di_configurazione");
    	std::cout << ifs.rdbuf();
    }
    
Devi accedere o registrarti per scrivere nel forum
5 risposte