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 :

Conception : Singleton et dérivation


Sujet :

C++

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut Conception : Singleton et dérivation
    Bonjour,

    j'aimerais dériver une classe singleton que j'utilisais jusqu'à lors en l'incluant.
    Je me suis aperçu qu'en fait il vallait mieux la dériver.

    Peut-on le faire ? Si oui, y at-il des contraintes particulières à faire cela ? Des recommandations ?

    La classe de base gère un service windows. Je désire donc faire une classe CApp dérivant de ma classe CService, tout en conservant l'unicité du singleton.

    CApp doit il être forcément désigné un singleton si CService est laissé singleton ?
    Ou plutôt en faire une classe abstraite et désigner CApp en singleton ?

    Merci par avance pour vos éclairages.

    @+

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Franchement, le seul rapport que je vois entre Singleton et dérivation, c'est qu'on implémente souvent le pattern Singleton avec une classe template, dont chaque classe singleton hérite en CRTP (Curiously Recurring Template Pattern).

    En clair:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template< class Type >
    class TSingleton< Type >
    {
    	static Type* ptr;
    };
     
    template< class Type >
    Type* TSingleton< Type >::ptr:
     
     
     
    class UneClasseSingleton : private TSingleton< UneClasseSingleton >
    {
    };
    Par contre, je ne sais pas exactement pourquoi on dérive ainsi. Je suppose que ça aide à forcer l'instanciation du template...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Un peu comme Medinoc, ton besoin me semble pour le moins étrange.
    En gros, ton CApp aura des responsabilités supplémentaires que CService : gérer le singleton + autre chose
    --> Problème de conception...

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Bonjour,
    merci pour vos réponses.

    Sinon, comme je le suggérais aussi :
    - CService est une classe abstraite (forcée à être dérivée). Elle gère toute la partie service windows.
    - CApp est un singleton dérivant de CService. Elle gère la partie spécifique de l'application.

    Cette conception tient-elle la route ?

    @+

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Sans plus d'infos, je dirais que oui...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    En ce sens, CService n'est pas un singleton, c'est CApp qui doit l'être puisque c'est lui qui est instancié; non?

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En effet, c'est CApp le singleton.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Sans plus d'infos, je dirais que oui...
    OK. Quelles infos supplémentaires pourraient être pertinentes ?

    En ce sens, CService n'est pas un singleton, c'est CApp qui doit l'être puisque c'est lui qui est instancié; non?
    Exact, et donc le seul truc qui me gêne dans cette solution, c'est que rien n'oblige à créer une classe dérivant de CService qui soit un singleton.
    Bon, aprés c'est aussi la responsabilité de celui qui dérive CService de ne pas faire n'importe quoi, non ?

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par olive_le_malin Voir le message
    Exact, et donc le seul truc qui me gêne dans cette solution, c'est que rien n'oblige à créer une classe dérivant de CService qui soit un singleton.
    Bon, aprés c'est aussi la responsabilité de celui qui dérive CService de ne pas faire n'importe quoi, non ?
    Tu pourras pas à partir du moment où c'est dérivé l'en empêcher. La chose que tu peux rajouter c'est non-copiable sur ta classe de base. Ca ne suffit pas mais ça peut mettre la puce à l'oreille.

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    OK. Il me suffit donc de ne pas implémenter le constructeur de copie et d'affectation.

    Merci à vous deux.

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ça n'empêchera personne d'instancier deux exemplaires de la classe.
    Beaucoup de classes sont protégées contre la copie, sans pour autant être supposées être uniques: Notamment, les flux.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ça n'empêchera personne d'instancier deux exemplaires de la classe.
    On est d'accord. Mais comment fais-tu pour imposer à une classe fille d'être un singleton. J'avoue que je ne vois pas trop.

  13. #13
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Citation Envoyé par olive_le_malin Voir le message
    OK. Il me suffit donc de ne pas implémenter le constructeur de copie et d'affectation.

    Merci à vous deux.
    Non il faut les déclaré en privée . Sinon le compilo t'en fournira.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  14. #14
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Goten Voir le message
    Non il faut les déclaré en privée . Sinon le compilo t'en fournira.
    Et ne pas les définir.

  15. #15
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    oui oui je les déclare en privé, mais je ne les implémente pas.

  16. #16
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Singletons et héritages se marient mal.

    Au moment où tu dérives un singleton, tu le désingletonises car tu pourras instancier une nouvelle classe dont une partie sera redondante avec le singleton initial.

    Quant à empêcher statiquement qu'une classe soit instanciée plus d'un fois ... bouaif. Regardez les deux plus belles définitions natives et génériques de singletons : celle de Loki, et celle de ACE (si on excepte l'emploi du double-lock sur cette dernière), elles sont toutes deux non intrusives : elles s'appliquent à des classes normales pour fournir quelques services supplémentaires : accesseur vers variable globale + construction paresseuse + politiques de destruction respectant les éventuelles dépendances.


    Bref, ce ne sont que des singletons, donc des variables globales, n'allez pas chercher la perfection, à tord ou à raison vous y avez déjà renoncé en utilisant une variable globale et ses couplages invisibles.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  17. #17
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Bonjour,

    Au moment où tu dérives un singleton, tu le désingletonises car tu pourras instancier une nouvelle classe dont une partie sera redondante avec le singleton initial.
    Je ne comprends pas pourquoi on le désingletonise.

    Sinon, par rapport au fait que ce ne soit pas une solution "parfaite", que suggères-tu comme solution dans mon cas pour faire sorte qu'il n'y ait qu'une seule instance ? Une classe "normale" dotée d'un compteur d'instance avec un assert si on en crée + d'un ?

    @+

  18. #18
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Bref, ce ne sont que des singletons, donc des variables globales, n'allez pas chercher la perfection, à tord ou à raison vous y avez déjà renoncé en utilisant une variable globale et ses couplages invisibles.
    Salut,
    Je ne suis pas sur de comprendre ce que tu as voulu dire : faut-il renoncer au pattern singleton au profit d'une variable globale - le singleton n'étant en définitive qu'une variable globale encapsulée.

  19. #19
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par olive_le_malin Voir le message
    Je ne comprends pas pourquoi on le désingletonise.

    Sinon, par rapport au fait que ce ne soit pas une solution "parfaite", que suggères-tu comme solution dans mon cas pour faire sorte qu'il n'y ait qu'une seule instance ? Une classe "normale" dotée d'un compteur d'instance avec un assert si on en crée + d'un ?@+
    Prenons le code suivant:
    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
    struct A : noncopyable { // dans une biblio "partagée"
        static A& instance() ;
        void f();
    protected:
        A();
    private:
        EtatQuineDoitSurtoutPasEtrePartage m_doitEtreUnique;
    };
     
    struct B : A { // dans un composant très métier
        static B&instance();
        void g();
    private:
        B();
    };
     
    void unCodeGeneriqueDUneBibliothequePartagee () {
        A::instance().f();
        ...
    }
     
    void unCodeSpecialise() {
        unCodeGeneriqueDUneBibliothequePartagee();
        B::instance().g();
    }
    Vois-tu le problème ?
    (si si, je vous assure, il y a gens qui écrivent ce genre d'horreurs)

    Pour ce qui est du comment on les écrit, personnellement, je n'impose pas grand chose (cf mon message dans le forum modélisation pour mon code type de singleton (qui répond à mes besoins).

    Ce qui est possible de faire quand tu veux un singleton qui puisse être dérivé (par un seul chemin!!) pour le spécialiser, c'est des trucs comme ça:
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    struct A:noncopyable {
        virtual void f();
    protected:
        A();
    private:
        EtatQuineDoitSurtoutPasEtrePartage m_doitEtreUnique;
    };
     
    struct B : A {
        virtual void f(); // on supplante
        void g();
    ...
    };
     
    struct THEA : noncopyable {
        static A& instance() {
            assert(m_instance && "THEA not initialized");
            return &m_instance;
        };
        static void init(A* instance) {
            assert(!m_instance && "THEA already initialized");
            m_instance = instance;
        }
    private:
        A * m_instance;
    };
    A* THEA::m_instance = 0; // dans 1 .cpp
     
    struct THEB : noncopyable {
        static B& instance() {
            assert(m_instance && "THEB not initialized");
            return &m_instance;
        };
     
        static void init(/*parameters ?*/) {
            assert(!m_instance && "THEB already initialized");
            m_instance = new B(/*parameters?*/);
            THEA::init(m_instance);
        }
    private:
        B * m_instance;
    };
    B* THEB::m_instance = 0; // dans 1 .cpp
     
    int main() {
        THEB::init(/*parameters?*/);
    }
    Mais ... la dérivation est-elle vraiment pertinente? Ne s'agit-il pas plutôt d'un problème de réutilisation de service depuis un autre singleton ?

    Citation Envoyé par 3DArchi Voir le message
    Je ne suis pas sur de comprendre ce que tu as voulu dire : faut-il renoncer au pattern singleton au profit d'une variable globale - le singleton n'étant en définitive qu'une variable globale encapsulée.
    Pas forcément. Je dis juste que ce n'est qu'une variable globale. Que nous sommes donc loin de faire quelque chose de "pur". Et que le mot "singleton" ne change pas grand chose... Donc inutile d'atteindre la "perfection" (comme p.ex. l'impossibilité statique d'avoir plusieurs instances, de forcer telle ou telle autre classe à être un singleton, etc), on y a déjà renoncé (en introduisant des couplages invisibles)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  20. #20
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Pas forcément. Je dis juste que ce n'est qu'une variable globale. Que nous sommes donc loin de faire quelque chose de "pur". Et que le mot "singleton" ne change pas grand chose... Donc inutile d'atteindre la "perfection" (comme p.ex. l'impossibilité statique d'avoir plusieurs instances, de forcer telle ou telle autre classe à être un singleton, etc), on y a déjà renoncé (en introduisant des couplages invisibles)
    Ok. Le pattern singleton traduit une variable globale. Malgré les inconvénients que tu mets en avant, il reste à mon sens un avantage qui est d'indiquer que l'on veut une unique instance de l'objet. Ce que la variable globale ne traduit pas à la simple lecture du code. Donc, il reste intéressant car il rajoute une information sur ce que l'on a voulu faire. En ce sens, il traduit une exigence de conception (même si le langage ne permet pas de la vérifier fortement).

Discussions similaires

  1. [PHP 5.3] Conception problématique avec Singleton
    Par MegaBigBoss dans le forum Langage
    Réponses: 12
    Dernier message: 21/12/2011, 19h31
  2. [conception] soucis sur un singleton
    Par r0d dans le forum C++
    Réponses: 12
    Dernier message: 11/07/2007, 11h03
  3. [conception] Logger singleton global
    Par r0d dans le forum C++
    Réponses: 1
    Dernier message: 30/03/2007, 20h13
  4. [Conception] Classe abstraite ou singleton
    Par speedster dans le forum Langage
    Réponses: 6
    Dernier message: 24/03/2007, 10h39

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