Frage zu Singleton, shared_ptr und static



  • Hallo alle zusammen, ich habe da mal eine Frage,

    Wenn ich die Funktion mit static schreibe, dann erstellt er beim ersten Aufruf ein Objekt und gibt es dann zurück, aber wenn dann func2() aufgerufen wird, dann erstellt er ein neues Objekt, so das ich nicht auf das Original zugreife.

    Wenn ich es ohne static schreibe, dann erstellt er beim ersten Aufruf ein Objekt, und ich kann in func1() und func2() auf das selbe zugreifen.

    Es wäre nett wenn mir einer von euch das Verhalten erklären würde.

    Ohne static

    typedef std::tr1::shared_ptr<sf::RenderWindow> RenderWindowPtr;
    
    inline RenderWindowPtr getRenderWindow()
    {
            static RenderWindowPtr window;
            if (window == 0)
                window.reset(new sf::RenderWindow);
            return window;
    }
    

    Mit static

    typedef std::tr1::shared_ptr<sf::RenderWindow> RenderWindowPtr;
    
    inline static RenderWindowPtr getRenderWindow()
    {
            static RenderWindowPtr window;
            if (window == 0)
                window.reset(new sf::RenderWindow);
            return window;
    }
    

    Beispiel:

    void func1()
    {
       RenderWindowPtr window = getRenderWindow();
       window->Draw();
    }
    
    void func2()
    {
       RenderWindowPtr window = getRenderWindow();
       window->Draw();
    }
    
    void test()
    {
        func1();
        func2();
    }
    

    Gruß, Daniel_S



  • Daniel_S schrieb:

    Wenn ich die Funktion mit static schreibe, dann erstellt er beim ersten Aufruf ein Objekt und gibt es dann zurück, aber wenn dann func2() aufgerufen wird, dann erstellt er ein neues Objekt, so das ich nicht auf das Original zugreife.

    Wenn ich es ohne static schreibe, dann erstellt er beim ersten Aufruf ein Objekt, und ich kann in func1() und func2() auf das selbe zugreifen.

    Es wäre nett wenn mir einer von euch das Verhalten erklären würde.

    Ich hätte eine Erklärung, falls func1 und func2 in verschiedenen Übersetzungseinheiten definiert wurden und getRenderWindow in einem Header definiert wurde, welcher in mehrere Übersetzungseinheiten eingebunden wird.

    Das würde zumindest Deine Beobachtung erklären; denn wenn Du eine Funktion mit static deklarierst hat sie "internal linkage". Das heißt, es wird mehrere Versionen davon geben --- in jeder Übersetzungseinheit, die diesen Header einbindet, eine eigene Version.

    Wenn Du das static weglässt, hat die Funktion "external linkage". Die gibt's dann nur einmal. Dass Du Dein Programm ohne static überhaupt übersetzen kannst, liegt daran, dass Du die Funktion als inline -Funktion deklarierst. Für diese Funktionen macht die "one definition rule" eine Aussahme. Ansonsten würde nämlich der Linker meckern ...

    Wie wär's mit folgendem:
    - DeKLARIERE die getRenderWindow-Funktion nur in einem Header
    - DeFINIERE sie in einer eigenen Übersetzungseinheit.
    - Lass inline weg

    HTH,
    SP



  • Sebastian Pizer schrieb:

    - DeKLARIERE die getRenderWindow-Funktion nur in einem Header
    - DeFINIERE sie in einer eigenen Übersetzungseinheit.
    - Lass inline weg

    - Lass static weg, Deine Funktion muss "external linkage" haben

    Gruß,
    SP



  • Ah, ja das stimmt. getRenderWindow() ist in einer Header deklariert und definiert, welche ich in mehrere cpp Dateien nutze.
    Vielen Dank für deine Erklärung.

    Gruß, Daniel_S


Anmelden zum Antworten