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++Builder Discussion :

Implémentation du design patern Singleton sous Borland C++ Builder XE [Débutant]


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2011
    Messages : 20
    Par défaut Implémentation du design patern Singleton sous Borland C++ Builder XE
    Bonjour à tous, et à toutes,

    Arrivant de .Net C# je démarre un projet en Borland C++ Builder (Embarcadero RAD Studio XE v2010 [v15.0.3953.35171]), et bien entendu j’ai du mal à retrouver mes petits…

    D’où ma nouvelle question toute bête : Je cherche à implémenter le design pater singleton sous Borland C++ Builder.
    J’ai cherché sur le net, je suis tombé sur divers exemples que j’ai testés dans mon projet Borland C++ Builder sans succès…

    Je suis en train d'essayer de m'inspirer de ce post pour essayer d'avancer : Plusieurs instances d'un singleton pour plusieurs modules


    Bon c’est un truc de base donc je suis sur que vous allez avoir un exemple, qui vas bien, d’implémentation de ce design à me proposer!

    Par contre, si possible :
    - Evités de donner un exemple avec une classe qui s’appelle singleton, car de suite ça devient vite incompréhensible.
    - Bien préciser le détail dans chaque fichier (.h pour la déclaration, .cpp pour la définition, .cpp avec le new pour l’utilisation).
    Le but étant que ce poste puisse servir ensuite à un novice qui chercherait l’info dans le forum.


    Merci d’avance à tous et à toute pour votre aide

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    Dans ton lien, Singleton est une template, c'est comme une macro mais appliqué aux classes, c'est ce que l'on appel les génériques, tu dois avoir la même chose en .NET non ? les méthodes anonymes et tout ça ?

    Ce template Singleton est réutilisable contrairement à l'exemple de la FAQ Comment faire pour empêcher de créer plus d'une instance d'une classe ? que tu as du lire vu ta reproche "Evitez de donner un exemple avec une classe qui s’appelle singleton, car de suite ça devient vite incompréhensible."
    As tu lu Présentation des principaux design patterns en C++ - III. Le singleton par Come David?

    Malheureusement la template est difficilement à un objet VCL hérité de TObject
    Hors le principal intérêt de C++ Builder c'est la VCL, sinon autant ne pas faire de C++Builder, les modifications nécessaires suppriment l'allocation statique donc la libération implicite, et malheureusement, on ne pas "templatisé" la libération, il faut y penser ...


    Je suis aussi un habitué de Singleton, j'ai adapté ma méthode que j'utilisais en Delphi, je ne sais pas si c'est la bonne !
    Je ne développe en C++ que depuis quelques mois et mes collègues ne développent pas en POO et Design Pattern, tout le code est dans les TForm, mais je dois bosser sur une partie avec une forte notion de généricité (interface, factory, strategy ...)

    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
    //---------------------------------------------------------------------------
    //                        TShaiORPersistentManager                         -
    //---------------------------------------------------------------------------
    class TShaiORPersistentManager : public TObject
    {
    private:
      // Membres Privés (Singleton)
      static TShaiORPersistentManager *FSingletonInstance;
     
      // Constructeurs Privés (Masqués)
      /*constructor*/__fastcall TShaiORPersistentManager();
     
    public:
      // Constructeurs Publiques
      /*destructor*/__fastcall ~TShaiORPersistentManager();
     
      // Méthodes Publiques (Singleton)
      static TShaiORPersistentManager* GetInstance();
      static void ReleaseInstance();
    };
    //---------------------------------------------------------------------------
    TShaiORPersistentManager * TShaiORPersistentManager::FSingletonInstance = NULL;
    //---------------------------------------------------------------------------
    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
    //---------------------------------------------------------------------------
    void SupervisionORClassesFinalization()
    {
      TShaiORPersistentManager::ReleaseInstance();
    }
    //---------------------------------------------------------------------------
    #pragma exit SupervisionORClassesFinalization
    //---------------------------------------------------------------------------
     
    //---------------------------------------------------------------------------
    //                        TShaiORPersistentManager                         -
    //---------------------------------------------------------------------------
    /*constructor*/__fastcall TShaiORPersistentManager::TShaiORPersistentManager()
    {
      ...
    }
     
    //---------------------------------------------------------------------------
    /*destructor*/__fastcall TShaiORPersistentManager::~TShaiORPersistentManager()
    {
      ...
    }
     
    //---------------------------------------------------------------------------
    /*static*/ TShaiORPersistentManager* TShaiORPersistentManager::GetInstance()
    {
      if ( ! FSingletonInstance)
      {
        FSingletonInstance = new TShaiORPersistentManager();
      }
      return FSingletonInstance;
    }
     
    //---------------------------------------------------------------------------
    /*static*/ void TShaiORPersistentManager::ReleaseInstance()
    {
      if (FSingletonInstance)
      {
        delete FSingletonInstance;
        FSingletonInstance = NULL;
      }
    }

    Tu peux aussi faire des objets C++ strict (sans VCL non-TObject), pour utilisation l'allocation statique (pas de new), un String par exemple c'est un objet utilisé souvent en allocation statique comme le TDateTime !
    Dans une DLL, c'est ce que j'ai fait, j'ai utilisé un objet c++ strict déclaré dans le DllEntryPoint

    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
     
      static CMaClassDLL DllExportObject;
     
      switch( reason )
      {
        case DLL_PROCESS_ATTACH :
          DllExportObject.DLLProcessAttach();
        break;
     
        case DLL_THREAD_ATTACH :
        case DLL_THREAD_DETACH :
        break;
     
        case DLL_PROCESS_DETACH :
          DllExportObject.DLLProcessDettach();
     
        break;
      }
    DllExportObject sera libéré lors de sortie de la fonction, c'est la durée de vie standard géré en portée de bloc { } d'une variable c

    le mot clé static me permet d'avoir la même variable entre chaque appel de DllEntryPoint par un même process (par plusieurs thread par exemple)
    ce static est différent du static des membres de classes, c'est pour rendre globale une variable locale (je l'ai interprété ainsi)

    Je t'avouerais que mon programme est conçu de tel sorte que LoadLibrary ne soit lancé qu'une seule fois (j'ai un système d'instance registry et de factory pour gérer mes classes et objets côté EXE encapsulant un tas de DLL implemetant un ensemble commun d'interfaces) donc je n'ai pas vraiement testé le comportement du static pour le moment, mon développement est en cours, j'ai encore plein de chose à faire !



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class CMaClassDLL
    {
    public:
      // Membres Publiques
      static CMaClassDLL* Instance;
     
      // Méthodes Publiques
      void DLLProcessAttach();  // Must Call on DLL_PROCESS_ATTACH
      void DLLProcessDettach(); // Must Call on DLL_PROCESS_DETACH
    };
    //---------------------------------------------------------------------------
    CMaClassDLL* CMaClassDLL::Instance = NULL;
    //---------------------------------------------------------------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void CMaClassDLL::DLLProcessAttach()
    {
      CMaClassDLL::Instance = this;
    }


    Les Objets VCL (TObject) ne peuvent être utilisés en instanciation dynamique avec new mais tu peux ou utiliser les std::auto_ptr mais je ne sais pas si peu le faire en global, j'en utilise jamais, je reste habitué au try finally du Delphi ou à la section finalization !

    Ah oui, contrairement au C# pas de Garbage Collector
    Il faut libérer la mémoire !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2011
    Messages : 20
    Par défaut
    Bonjour ShaiLeTroll,

    Et encore une fois merci pour ta réponse, qui comme à l’habitude es claire, nette et précise, rempli d’exemples nickel pour toutes les situations.

    Alors je te réponds dans l’ordre :
    L’idée du template est une bonne idée, car ça évite, bien entendu, de recoder à chaque fois le singleton dans toutes les classes qui l’utilise.

    Maintenant je t’avoue que je suis un peu perplexe quant à la mise en œuvre :
    Tout le code du template tu le mets dans un fichier .h, et ensuite tu mets une référence à ce .h dans chaque .h des classes qui l’utilisent?

    [Edit:] Je me répond à moi même.
    C'est exactement ce que j'indiquais: J'ai pris le template de cet exemple Plusieurs instances d'un singleton pour plusieurs modules, le template dans un .h que j'ai appeler Singleton, mis en référence dans le .h de ma classe Test qui utilise le singleton et ça marche nickel!

    Pour le lien Comment faire pour empêcher de créer plus d'une instance d'une classe ? je l’avais bien vu et je l’ai zappé, car son implémentation ne me convenait pas, trop loin de ce que je connais!
    Je préfère de loin ton exemple, au moins on sait de quoi on parle!

    Pour la Présentation des principaux design patterns en C++ - III. Le singleton par Come David, et bien justement c’est ce que je cherchais dans le forum C++ Builder… Comme je n’ai pas trouvé dans ce forum, je n’ai pas eu le réflexe, à tort je l’avoue, de chercher dans le forum C++. Honte à moi…
    Maintenant j’ai tout ce qu’il me faut sous la main.

    Pour les objets C++ strict, je ne connais pas trop… J’ai du mal avec les statics… Je préfère allouer mes petits et ensuite les détruire…
    Mais je vais regarder de plus près cet exemple, histoire d’en apprendre un peux plus… Surtout que normalement je vais avoir géré du multithread dans mon app…

    Pour la mémoire, t’inquiètes même si j’arrive de .Net, il me reste en tête des notions de base de C++ de ma formation initiale (BTS) : Donc un new, un delete, sinon bonjour les fuites mémoires…

    En tout cas encore merci pour ta réponse, et pour les exemples.
    C’est vraiment super d’être tombé sur quelqu’un comme toi qui sais de quoi il parle et qui es super réactif.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. combox sous borland c++ builder 6
    Par themarki dans le forum C++Builder
    Réponses: 0
    Dernier message: 16/06/2008, 09h14
  2. messagebox sous borland c++ builder
    Par themarki dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/06/2008, 12h22
  3. Réponses: 2
    Dernier message: 11/06/2008, 10h55
  4. Implémentation du design pattern singleton
    Par 0pierrot0 dans le forum C++
    Réponses: 1
    Dernier message: 22/01/2008, 10h01
  5. Problème avec GLUT sous borland c++ builder X
    Par hiko-seijuro dans le forum GLUT
    Réponses: 1
    Dernier message: 04/11/2004, 12h47

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