IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Singleton en C++


Sujet :

C++

  1. #1
    Membre �clair�

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par d�faut Singleton en C++
    Bonjour,

    Je me suis toujours demande (dans un contexte monothread) pourquoi, pour �crire un singleton Widget, on ne fait g�n�ralement pas :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    static Widget& instance()
    {
      static Widget w;
      return w;
    }
    ou bien :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    static Widget& instance()
    {
      static Widget* w = new Widget();
      return *w;
    }

    plut�t qu'utiliser un membre static de la classe Widget :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    class Widget
    {
    public:
    ...
     
    static Widget& instance()
    {
      if (!w)
      {
        w = new Widget;
      }
      return *w;
    }
    ...
     
    private:
    static Widget* w;
    };
     
    Widget* Widget::w = 0;
    Ce qui est qd m�me plus long � �crire ...

  2. #2
    R�dacteur
    Avatar de farscape
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par d�faut
    salut,
    dans ton cas tu n'as besoin apparemment que d'une fonction globale ,
    mais si ton singleton propose d'autres services comme la lib�ration de la ressource allou�e, dans ce cas une classe est plus pratique qu'une fonction globale.
    la deuxi�me forme d'allocation de ta ressource peut �tre obligatoire si elle a besoin d'un contexte pr�cis pour �tre instanci�e. (d�pendance avec une autre ressource de l'application).
    donc �a depend de la ressource a partager ,si elle est autonome ou non,
    autre point avec des outils comme intellisense (visual c++) je pr�f�re passer par une classe c'est plus pratique a l'utilisation mais plus long a �crire...

  3. #3
    Membre Expert

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 49
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - Op�rateur de t�l�communications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par d�faut
    Citation Envoy� par vandamme Voir le message
    Bonjour,

    Je me suis toujours demande (dans un contexte monothread) pourquoi, pour �crire un singleton Widget, on ne fait g�n�ralement pas :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    static Widget& instance()
    {
      static Widget w;
      return w;
    }
    C'est le singleton de Meyer.

    Citation Envoy� par vandamme Voir le message
    ou bien :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    static Widget& instance()
    {
      static Widget* w = new Widget();
      return *w;
    }
    Ca, c'est une des formes canoniques.

    Citation Envoy� par vandamme Voir le message
    plut�t qu'utiliser un membre static de la classe Widget :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    class Widget
    {
    public:
    ...
     
    static Widget& instance()
    {
      if (!w)
      {
        w = new Widget;
      }
      return *w;
    }
    ...
     
    private:
    static Widget* w;
    };
     
    Widget* Widget::w = 0;
    Ce qui est qd m�me plus long � �crire ...
    Et �a, c'est le singleton tel qu'il est pr�sent� dans le GoF95 - la forme canonique de base.

    Chacune des impl�mentations a sa sp�cificit� (les deux formes canoniques sont �quivalentes, mais le destructeur de Widget n'est pas appel�. Le destructeur du singleton de Meyer est appel�, mais il est difficile voire impossible de savoir quand).

    Ensuite, le choix de l'impl�mentation d�pends du projet sur lequel tu travailles. La question de savoir quelle est la forme la plus facile a d�finir n'a pas v�ritablement d'int�r�t, puisque la bonne r�ponse � cette question d�pends de l'environnement dans lequel le singleton est int�gr�.
    [FAQ des forums][FAQ D�veloppement 2D, 3D et Jeux][Si vous ne savez pas ou vous en �tes...]
    Essayez d'�crire clairement (c'est � dire avec des mots fran�ais complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Caf�. C'est d�pass� tout �a.
    Et si vous �tes sages, vous aurez peut �tre vous aussi la chance de passer � la t�l�. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    Membre �m�rite Avatar de valefor
    Profil pro
    Inscrit en
    D�cembre 2006
    Messages
    711
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2006
    Messages : 711
    Par d�faut
    Anecdote :

    Avec une vieille impl�mentation de gcc, sous Solaris, j'ai eu un probl�me un jour avec ces singletons.

    On faisait un chargement dynamique de biblioth�que.
    De cette biblioth�que on r�cup�rait un singleton.
    On d�chargeait la biblioth�que.
    On arr�tait le programme et paf segv (que l'on n'a pas vu dessuite, on a cru pendant longtemps que tout fonctionnait bien).

    Le probl�me venait que le destructeur du singleton �tait appel� apr�s d�chargement de la lib.

    Avec les versions plus r�centes de gcc le probl�me a �t� r�solu.

  5. #5
    screetch
    Invit�(e)
    Par d�faut
    en quoi une nouvelle version de gcc resout le probleme ?

  6. #6
    Membre �m�rite Avatar de valefor
    Profil pro
    Inscrit en
    D�cembre 2006
    Messages
    711
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2006
    Messages : 711
    Par d�faut
    Elle r�solvait le probl�me au niveau des atexit ou un truc comme cela... l'ordre dans le quel les fonctions de destruction �taient enregistr�es tenait compte du d�chargement des biblioth�ques :
    Avant tout les destructeurs �taient enregistr�s � la fin du programme.
    Apr�s, je ne sais plus comment cela marchait mais il n'y avait plus le probl�me.

  7. #7
    Membre chevronn�
    Inscrit en
    Novembre 2006
    Messages
    362
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par d�faut
    Bonjour,

    Je trouve vos r�ponses (Farscape et Emmanuel Deloget) assez mesur�es, il me semble que l'on n'a pas vraiment le choix.

    Il me semble que, si l'on veut g�rer l'ordre de destruction des singletons, nous sommes "forc�s" d'utiliser un
    plut�t qu'un
    ,
    cf la FAQ ici.

    Du coup, ce serait une entorse � la segmentation des responsabilit�s du code de ne pas g�rer la d�sallocation du pointeur au m�me endroit que son allocation, c'est � dire dans un objet singleton.

    C'est vrai que si on fait diff�remment, on n'est pas certain que cela se passe mal : il se peut qu'au cours de la dur�e de vie du projet, personne n'ajoute jamais aucun autre singleton, ou que les nouveaux singletons ne d�pendent jamais des anciens pour leurs construction ou leur destruction.

    Mais cela me semble �tre du m�me ordre que pas mal d'autres risques que l'on ne prend pas : il se peut que si l'on n'initialise pas des variables ou si l'on n'alloue pas de la m�moire avant de s'en servir, on n'obtienne jamais de crash ni de fonctionnement aberrant. Et pourtant on ne fait jamais d'entorse � ces r�gles, m�me quand on est sur et certain que cela se passera bien.

    Du coup, je me dis qu'il y a quelque chose que j'ai mal compris.
    Pourriez-vous m'�clairer ?
    Merci par avance

  8. #8
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    C'est tout l'avantage de passer par une classe qui contient un pointeur vers l'�l�ment statique

    A partir du moment o� ton pointeur est encapsul�, rien ne t'emp�che de cr�er des m�thodes qui renverront une r�f�rence sur l'instance plut�t qu'un pointeur sur celle-ci...

    En effet, tu peux tout aussi bien bien avoir un code proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Singleton
    {
        public:
            static Singleton& getInstance()
            {
                 if(!instance)
                     instance= new Singleton;
                 return *instance;
            }
            static void freeInstance()
            {
                delete instance;
                instance = NULL;
            }
        private:
            static Singleton *instance;
    };
    que de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Singleton
    {
        public:
            static Singleton* getInstance()
            {
                 if(!instance)
                     instance= new Singleton;
                 return instance;
            }
            static void freeInstance()
            {
                delete instance;
                instance = NULL;
            }
        private:
            static Singleton *instance;
    };
    et, si ton singleton d�pend d'un autre singleton, rien ne t'emp�cherait m�me d'�crire un code proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class Singleton
    {
        public:
            static Singleton& getInstance()
            {
                 /* Singleton2::getInstance() renvoie également une référence
                  * sur l'instance ;)
                  */
     
                 if(!instance)
                     instance= new Singleton(Singleton2::getInstance());
     
                 /* ou, de manière plus lisible: */
                 if(!instance)
                 {
                     Singleton2 s2=Singleton2::getInstance();
                     instance = new Singelton(s2);
                 }
                 /* renvoi de la référence sur l'instance */
                 return *instance;
            }
            static void freeInstance()
            {
                delete instance;
                instance = NULL;
            }
        private:
            static Singleton *instance;
    };
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  9. #9
    Membre �clair�

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par d�faut
    Et bien merci beaucoup pour vos r�ponses constructives.

  10. #10
    Membre Expert

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 49
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - Op�rateur de t�l�communications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par d�faut
    Pour ma part, et je sais que je vais en surprendre plus d'un, je ne vois pas d'int�r�t � vouloir absolument que le singleton soit d�truit � un moment quelconque du programme (y compris une fois que main() a fini de s'ex�cuter). Nous sommes dans un monde simplifi�, ou l'OS prends en charge l'unload do process et termine toutes les ressources allou�es par ce process. De fait, la m�moire, les fichiers ouverts, etc sont correctement lib�r�/ferm�/etc � la fin du programme.

    Certes, on peut toujours me r�pondre "�a fait un resource leak ! ". Et bien non: puisque le singleton est cens� �tre valide � partir du moment ou il est instanci� et jusqu'� la fin du programme (c'est � dire, dans un sens, jusqu'� ce que le dernier destructeur de la derni�re instance qui a une dur�e de vie statique ait fini de s'ex�cuter), quel leak est-ce que je cr�e si je ne le lib�re pas en quittant ? Aucun, puisque sit�t apr�s l'ex�cution du destructeur du singleton, on est cens� redonner la main � l'OS pour qu'il fasse le clean up.

    En fait, si on donne � l'utilisateur la possibilit� de d�truire le singleton quand il le souhaite, on prends le risque de l'autoriser � l'utiliser apr�s qu'il ait �t� d�truit - ce qui est bien plus ennuyeux que de ne pas le d�truire au niveau de la maintenance du code.

    J'en entends d�j� qui me hurlent "mais un utilisateur lambda ne ferais pas �a!". Certes. C'est possible. Le m�me utilisateur lambda ne d�clarera pas deux instances de la m�me classe si vous lui dites qu'il n'en a pas le droit. Puisque vous vous substituez � son intelligence en interdisant la cr�ation d'une seconde instance de votre classe, pourquoi lui permettre de la d�truire apr�s ? Ca n'est pas tr�s consistant
    [FAQ des forums][FAQ D�veloppement 2D, 3D et Jeux][Si vous ne savez pas ou vous en �tes...]
    Essayez d'�crire clairement (c'est � dire avec des mots fran�ais complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Caf�. C'est d�pass� tout �a.
    Et si vous �tes sages, vous aurez peut �tre vous aussi la chance de passer � la t�l�. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  11. #11
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Citation Envoy� par Emmanuel Deloget Voir le message
    Pour ma part, et je sais que je vais en surprendre plus d'un, je ne vois pas d'int�r�t � vouloir absolument que le singleton soit d�truit � un moment quelconque du programme (y compris une fois que main() a fini de s'ex�cuter). Nous sommes dans un monde simplifi�, ou l'OS prends en charge l'unload do process et termine toutes les ressources allou�es par ce process. De fait, la m�moire, les fichiers ouverts, etc sont correctement lib�r�/ferm�/etc � la fin du programme.

    Certes, on peut toujours me r�pondre "�a fait un resource leak ! ". Et bien non: puisque le singleton est cens� �tre valide � partir du moment ou il est instanci� et jusqu'� la fin du programme (c'est � dire, dans un sens, jusqu'� ce que le dernier destructeur de la derni�re instance qui a une dur�e de vie statique ait fini de s'ex�cuter), quel leak est-ce que je cr�e si je ne le lib�re pas en quittant ? Aucun, puisque sit�t apr�s l'ex�cution du destructeur du singleton, on est cens� redonner la main � l'OS pour qu'il fasse le clean up.

    En fait, si on donne � l'utilisateur la possibilit� de d�truire le singleton quand il le souhaite, on prends le risque de l'autoriser � l'utiliser apr�s qu'il ait �t� d�truit - ce qui est bien plus ennuyeux que de ne pas le d�truire au niveau de la maintenance du code.

    J'en entends d�j� qui me hurlent "mais un utilisateur lambda ne ferais pas �a!". Certes. C'est possible. Le m�me utilisateur lambda ne d�clarera pas deux instances de la m�me classe si vous lui dites qu'il n'en a pas le droit. Puisque vous vous substituez � son intelligence en interdisant la cr�ation d'une seconde instance de votre classe, pourquoi lui permettre de la d�truire apr�s ? Ca n'est pas tr�s consistant
    Je me ralie sans difficult� � ton point de vue, et je le prendrai en consid�ration dans le futur.

    Cependant, je me dis qu'il faut peut �tre temp�rer un peu le raisonnement en fonction du but recherch� par le singleton...

    En effet, dans quelle mesure la destruction (et la "re-cr�ation") du singleton n'est elle pas la possibilit� de s'assurer d'une lib�ration correcte des ressources utilis�es par celui-ci afin de permettre de repartir sur "une feuille blanche" dans certains cas particuliers

    Je pense entre autre, et m�me si je pr�vois que tu va hurler � la lecture de ceci, � un singleton dont l'objectif serait de g�rer des ressources diff�rentes selon les "niveaux" ou les "cartes" dans un jeu en pr�sentant plusieurs, avec des sons, des images et des repr�sentations graphiques diff�rentes...

    Mais je crois que la probl�matique vient plus au fait qu'il faille s'assurer de l'existence d'une instance coh�rente , que l'on veut unique, et de s'assurer de pouvoir la r�cup�rer de mani�re s�curis�e que du fait que l'on permette (ou non) � l'utilisateur de la lib�rer...
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  12. #12
    Membre chevronn�
    Inscrit en
    Novembre 2006
    Messages
    362
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par d�faut
    Rebonjour � tous,

    Citation Envoy� par Emmanuel Deloget Voir le message
    Pour ma part, et je sais que je vais en surprendre plus d'un, je ne vois pas d'int�r�t � vouloir absolument que le singleton soit d�truit � un moment quelconque du programme (y compris une fois que main() a fini de s'ex�cuter).
    Int�ressant... J'avoue ne pas savoir quoi en penser.

    Je suis bien d'accord avec toi quand tu dis
    Citation Envoy� par Emmanuel Deloget Voir le message
    En fait, si on donne � l'utilisateur la possibilit� de d�truire le singleton quand il le souhaite, on prends le risque de l'autoriser � l'utiliser apr�s qu'il ait �t� d�truit - ce qui est bien plus ennuyeux que de ne pas le d�truire au niveau de la maintenance du code.
    En m�me temps, je suis aussi convaincu du fait que si l'on veut d�truire les Singletons, il faut le faire � la main. Faute de quoi on prend le risque de ne pas les d�truire dans le bon ordre.

    Du coup, je suis perplexe quant � ta proposition de ne pas les d�truire.

    Quant � la remarque suivante :
    Citation Envoy� par koala01
    Je pense entre autre, et m�me si je pr�vois que tu va hurler � la lecture de ceci, � un singleton dont l'objectif serait de g�rer des ressources diff�rentes selon les "niveaux" ou les "cartes" dans un jeu en pr�sentant plusieurs, avec des sons, des images et des repr�sentations graphiques diff�rentes...
    Et bien je hurle en effet. On en le r�p�tera jamais assez : minimisons l'utilisation des singletons. Les singletons c'est pratique � coder, mais c'est super-p�nalisant quand on veut faire �voluer son programme. Qui plus est, cela cache souvent un d�faut de conception.
    Il suffit d'utiliser un singleton quelque part pour se rendre compte qu'on avait en fait besoin de plusieurs objets (ou qu'on aurait pu avoir besoin de plusieurs objets). Le cas cit� : g�rer des jeux de ressources diff�rents, en est un exemple.

    Bonne journ�e.

  13. #13
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    D�veloppeur de jeux vid�o
    Inscrit en
    Ao�t 2004
    Messages
    1 717
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur de jeux vid�o
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 1 717
    Par d�faut
    Sur le point de la destruction et la cr�ation, j'ai dans mon projet personel quelques objets singleton qui ne sont cr��s puis d�truit que sur demande.
    Je prends par exemple le syst�me graphique : il ne doit pas �tre cr�� imm�diatement parce-que plusieurs traitements doivent �tre effectu�s avant sa cr�ation. De m�me, je dois pouvoir le d�truire compl�tement (au sens : pas seulement le d�s-initialiser, mais bien le d�truire) et le recr�er par la suite sans avoir � relancer mon application.
    J'ai quelques syst�mes qui marchent comme �a et qui doivent toute de m�me �tre singleton pour profiter des propri�t�s cit�es au dessus. J'ai aussi des singletons qui n'ont pas besoin d'�tre potentiellement d�truit sur demande, mais ils sont rare.

    Comme quoi, ce n'est pas toujours interessant d'avoir un singleton "durant tout le temps de l'application", m�me si c'est en grande partie vrai.

    Une note a part : vivement que les mecs de boosts se mettent d'acord sur la lib de singleton...

  14. #14
    Alp
    Alp est d�connect�
    Expert confirm�

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par d�faut
    Le singleton est un sujet r�current sur ce forum.
    Une petite recherche avanc�e sur le mot singleton dans le forum C++ donne d�j� pas mal d'�l�ments de r�ponse, en particulier par rapport aux interventions de sp�cialistes

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [Servlet]Singleton & cache
    Par lucimast dans le forum Servlets/JSP
    R�ponses: 4
    Dernier message: 15/12/2004, 16h36
  2. Singleton h�ritable ?
    Par rolkA dans le forum C++
    R�ponses: 10
    Dernier message: 11/12/2004, 16h22
  3. [D�butant] pattern singleton
    Par SirDarken dans le forum D�buter avec Java
    R�ponses: 22
    Dernier message: 11/12/2004, 01h55
  4. Mutiple row in singleton select ????? [Important, merci]
    Par SkyDev dans le forum Bases de donn�es
    R�ponses: 6
    Dernier message: 20/04/2004, 14h02
  5. [debutant]Singleton
    Par bafman dans le forum Langage SQL
    R�ponses: 6
    Dernier message: 13/01/2004, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo