Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Singleton RenderWindow  (Lu 5290 fois)

0 Membres et 1 Invité sur ce sujet

Xnerdz

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
    • E-mail
Singleton RenderWindow
« le: Avril 29, 2012, 05:56:10 pm »
Bonjour.

J'aimerais faire un singleton qui contient ou hérite d'un RenderWindow.
Il semblerait que je ne puisse pas le déclarer en static  :'(

Ça fait déjà plusieurs heurs que je travail la dessus et il semble que le seul moyen d'y parvenir est de déclarer le singleton en pointeur tout comme le renderwindow d'ailleur, et de les allouer ensuite après l'initialisation du main.

Mon problème est que j'ai besoin de ce singleton pour avoir tous mes points dans mon travail scolaire et que je ne peux pas utiliser la technique des pointeurs mentionnés, car il faut alors créé une sorte de methode "destroy" pour aller "delete" le singleton à la fin du programme et ce n'est pas de la bonne programmation que dit mon prof de toute façon.

Comment dois-je créé mon singleton utilisant un RenderWindow?  ???

lezebulon

  • Full Member
  • ***
  • Messages: 235
    • Voir le profil
Re : Singleton RenderWindow
« Réponse #1 le: Avril 29, 2012, 06:35:05 pm »
C'est quoi qui t'empêche de déclarer en static? A mon avis ça devrait être possible, poste-nous le code qui ne va pas

Xnerdz

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
    • E-mail
Re : Singleton RenderWindow
« Réponse #2 le: Avril 29, 2012, 06:56:14 pm »
Oui, j'avait oublier  :P

GameWindow.h
class GameWindow
{
public:
static GameWindow& GetInstance();

private:
GameWindow(void);
~GameWindow(void);
GameWindow(const GameWindow& _source);
GameWindow& operator = (const GameWindow& _source);

static GameWindow instance;
static sf::RenderWindow* screen;
};

GameWindow.cpp
#include "GameWindow.h"

GameWindow GameWindow::instance;

GameWindow::GameWindow(void)
{
this->screen = new sf::RenderWindow();
}

GameWindow::~GameWindow(void)
{
delete screen;
}

GameWindow& GameWindow::GetInstance()
{
return instance;
}

Que je mette "sf::RenderWindow* screen;" static ou non j'ai des problèmes...
Si j'le mets pas, j'ai une violation d'écriture dans mlock.
Si j'le met, j'ai des symboles externes non résolus.
« Modifié: Avril 29, 2012, 07:09:21 pm par Xnerdz »

Koryushin

  • Jr. Member
  • **
  • Messages: 93
    • Voir le profil
Re : Singleton RenderWindow
« Réponse #3 le: Avril 29, 2012, 08:13:43 pm »
En fait pour les attributs static, ils faut abord les initialiser en dehors des méthodes.
En début de ton fichier GameWindow.cpp ou il faut écrire :

sf::RenderWindow* GameWindow::screen = (sf::RenderWindow*)NULL;
GameWindow* GameWindow::instance =(GameWindow*)NULL;

en déclarant instance comme un pointeur dans le .h

Xnerdz

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
    • E-mail
Re : Re : Singleton RenderWindow
« Réponse #4 le: Avril 29, 2012, 08:33:00 pm »
sf::RenderWindow* GameWindow::screen = (sf::RenderWindow*)NULL;
GameWindow* GameWindow::instance =(GameWindow*)NULL;

en déclarant instance comme un pointeur dans le .h

Mille fois merci!  :D

J'ai toutefois, un autre petit souci qui se crée alors. :P
Si j'utilise dynamiquement l'instance de mon singleton, je dois alors aussi le supprimer.
Ce que j'ai remarqué c'est que, quand je met un "break point" dans le destructeur de GameWindow, il n'est jamais lu.
Cela m'inquiète un peu, car delete instance; et delete screen; ne seront jamais appelé et... tu sait... les memory leeks...  :-\

Est-ce que les classes static on besoin d'un destructeur?  ???

Bref, cela revient à mon problème de départ où je dois appeler le destructeur à la main et ça, ce n’est pas de la programmation conventionnelle.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Singleton RenderWindow
« Réponse #5 le: Avril 29, 2012, 08:48:00 pm »
Tu peux utiliser la forme la plus simple du singleton, si ses inconvénients n'en sont pas pour toi (initialisation non thread-safe avec un compilo pre-C++11, destruction après la fin du main(), impossible de contrôler l'ordre si plusieurs singletons inter-dépendants).

class GameWindow
{
public:

    static GameWindow& GetInstance()
    {
        static GameWindow instance;
        return instance;
    }

    ...
};
 

Et pourquoi avoir un membre statique (autre que l'instance de la classe) dans une classe singleton ?
Laurent Gomila - SFML developer

Xnerdz

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
    • E-mail
Re : Re : Singleton RenderWindow
« Réponse #6 le: Avril 29, 2012, 09:07:53 pm »
class GameWindow
{
public:

    static GameWindow& GetInstance()
    {
        static GameWindow instance;
        return instance;
    }

    ...
};
 
Je vais essailler ça ce soir  :)

Et pourquoi avoir un membre statique (autre que l'instance de la classe) dans une classe singleton ?
Parce que j'ai pas dormit de la nuit?  ;D

Merci pour les réponses rapides.

lezebulon

  • Full Member
  • ***
  • Messages: 235
    • Voir le profil
Re : Singleton RenderWindow
« Réponse #7 le: Avril 29, 2012, 09:18:55 pm »
En fait le destructeur de ton object static est bien appellé, mais après le main.

@Laurent : c'est thread-safe de faire ça en C++11? Comment ça se fait ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Singleton RenderWindow
« Réponse #8 le: Avril 29, 2012, 10:36:48 pm »
Citer
@Laurent : c'est thread-safe de faire ça en C++11? Comment ça se fait ?
Parce qu'ils ont rajouté cette garantie dans le standard, tout simplement.
Laurent Gomila - SFML developer

Koryushin

  • Jr. Member
  • **
  • Messages: 93
    • Voir le profil
Re : Singleton RenderWindow
« Réponse #9 le: Avril 30, 2012, 12:23:25 am »
tu peux passer par une classe template pour créer ton singleton.

////////////////////////////////////////////////////////////
/// Template servant à construire les classes singleton
////////////////////////////////////////////////////////////
template <class T>
class CSingleton
{
public :

        //----------------------------------------------------------------
        // Renvoie l'instance unique de la classe
        //----------------------------------------------------------------
        static T* GetInstance()
        {
                if (!Inst)
                        Inst = new T;

                return Inst;
        }

        //----------------------------------------------------------------
        // Détruit l'instance unique de la classe
        //----------------------------------------------------------------
        static void Destroy()
        {
                delete Inst;
                Inst = NULL;
        }

protected :

        //----------------------------------------------------------------
        // Constructeur par défaut
        //----------------------------------------------------------------
        CSingleton() {}

        //----------------------------------------------------------------
        // Destructeur
        //----------------------------------------------------------------
        ~CSingleton() {}

private :

        //----------------------------------------------------------------
        // Données membres
        //----------------------------------------------------------------
        static T* Inst; ///< Instance unique de la classe

        //----------------------------------------------------------------
        // Copie interdite
        //----------------------------------------------------------------
        CSingleton(const CSingleton&);
        CSingleton& operator =(const CSingleton&);
};

template <class T> T* CSingleton<T>::Inst = (T*)NULL;


 

et ta classe GameWindow hérite de CSingleton de la maniere suivante

class GameWindow : public CSingleton<GameWindow >
{
   friend class CSingleton<GameWindow >;

   protected:

      GameWindow ();
      ~GameWindow();
    ...
};

 

« Modifié: Avril 30, 2012, 01:32:46 am par Koryushin »

Xnerdz

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
    • E-mail
Re : Singleton RenderWindow
« Réponse #10 le: Avril 30, 2012, 05:53:02 am »
Merci pour toute ces réponses!

Citer
    static GameWindow& GetInstance()
    {
        static GameWindow instance;
        return instance;
    }
Laurent, j'ai essayé ça tantôt.
Petite question, est-ce que instance est alors réaffecté à chaque appel de GetInstance()?

Citer
En fait le destructeur de ton object static est bien appellé, mais après le main.
Vraiment? :o ça expliquerait pourquoi j'entre jamais dedans avec mon breakpoint.   ::)
J'ai vérifié tout ça au Virtual Leek Detector et en effet, ya aucune fuite.  ;D

Merci
template <class T>
class CSingleton
...
Mais la je vais plutôt opté pour une solution un peu plus simpliste. :P

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Singleton RenderWindow
« Réponse #11 le: Avril 30, 2012, 08:11:28 am »
Citer
Petite question, est-ce que instance est alors réaffecté à chaque appel de GetInstance()?
Ben... non. Sinon ce serait un peu con, et surtout ce ne serait pas un singleton. :P
Tu ne connais pas les variables statiques de fonction ?

Citer
ça expliquerait pourquoi j'entre jamais dedans avec mon breakpoint.
Normalement ça ne gêne pas, le debugger ne s'arrête pas quand main() retourne.
Laurent Gomila - SFML developer

Xnerdz

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
    • E-mail
Re : Singleton RenderWindow
« Réponse #12 le: Avril 30, 2012, 08:15:31 am »
D’acore, merci pour tout.  ;D

 

anything