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 :

Pointeur de fonctions membres


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 70
    Points : 50
    Points
    50
    Par défaut Pointeur de fonctions membres
    Bonjour à tous,

    J'ai un problème de conception que je n'arrive pas à résoudre.

    J'aimerais créer un objet qui puisse appeler les méthodes d'autres objets.
    C'est dans le cadre d'une console graphique. J'aimerais avoir l'objet "Console" d'un coté, et depuis l'objet, disons "Ecran" binder la méthode "resize" depuis la classe "Ecran" à ma console.
    Et qu'ensuite avec la console, appeler un objet de type "Ecran" et sa méthode "resize" quand je tape une commande que j'aurais définie pendant le bind.

    Seulement, je n'arrive pas à stocker des pointeurs de fonctions membres dans un containeur, parce qu'évidemment le type diffère.
    Et je n'y arrive pas non plus avec les templates. Le compilateur m'oblige à faire un containeur par type.

    Est ce que quelqu'un à une idée ? Il n'y aurait que le nom de la classe qui diffère.
    Je vais forcer le prototype à "std::string fonction (const std::string & param)", ça suffira amplement.

    J'ai déjà tenté le tutorial de Laurent Gomila, mais j'ai pleins d'erreurs à la compilation dû aux templates et à des appels de méthode virtuelle non définie.
    Il y a un peu trop d'étapes, alors je ne sais pas par où commencer pour comprendre les problèmes de compilation.
    Je suis avec GCC(-std=c++0x) sous linux. C'est peut-être pour ça que j'ai un tas de bugs avec les templates.
    J'ai l'habitude d'instancier mes templates dans un fichier spécial. Ici je vois pas quoi instancier... Autant être franc, je comprend rien lol.

    NOTE : je me suis planté de forum, il y a moyen qu'un modérateur me le déplace dans le forum général C++. Merci.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    D'après les informations que tu donnes, je ne vois pas l'intérêt d'utiliser des pointeurs sur fonctions membres. Si tu veux définir des associations entre des mots-clefs et des appels de méthode, pourquoi ne pas tout simplement créer des objets commande capable d'une part de reconnaître un mot-clef, et d'autre part d'appeler une méthode sur une référence à laquelle ils sont liés à l'instanciation. Ce que tu demandes ressemble à de la réflexion sur fonction, mais je ne crois pas que C++ sache faire ça...donc tu devras de toutes façons le coder d'une manière ou d'une autre.

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 70
    Points : 50
    Points
    50
    Par défaut
    J'ai essayé avec des objets fonctions.

    J'ai un objet générique pour la commande.
    Ensuite pour chaque classe à laquelle je souhaite lier des commandes en console, j'ai un objet commande enfant (J'ai fait ça avec des templates).

    Ensuite, dans ma console, je peux faire un vecteur d'objets commandes génériques.
    Simplement j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    commandGeneric * newCmd = new commandSpecific(monObjetParticulier, &monObjetParticulier::laMethodeQuiVaAvec);
     
    m_mesCommandes.push_back( newCmd );
    Ensuite, C++ ne m'interdit pas en partant de l'objet parent d'utiliser les commandes enfants. En faisant de la surcharge d'opérateur () au niveau du parent une méthode virtuelle pure (Comme ça je suis sûr que le compilateur criera s'il utilise la version du parent).
    Je ne sais pas si c'est bien, mais ça fait plus ou moins ce que j'aimerais. Maintenant, je trouve ça un peu bizarre, je comprends pas comment ça peut marcher.

    Pour la destruction des objets alloués pour les commandes, c'est la console qui s'occupe de parcourir tout le vecteur à sa destruction en détruisant chaque commande.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    comment ça marche? Tu as fait ce qu'on appelle un type erasure: une classe mère non-template avec une interface commune qui permet d'utiliser les classes dérivées templatisées "comme des" commande génériques (principe fondamental pour utiliser l'héritage.
    Si ça répond à ton problème c'est OK!
    Par curiosité, comment fais-tu la reconnaissance mot-clef->commande?

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 70
    Points : 50
    Points
    50
    Par défaut
    D'accord, on peut dire que c'est une interface en POO ?

    Pour la reconnaissance, c'est vrai qu'avec un vecteur c'est un peu weird , mais j'ai volontairement simplifier le code ici pour ne pas parasiter ma question. Sinon j'utilise un container map.

    L'objet fonction générique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class Functor
    {
    	public:
    		/* === Public constructors & destructor === */
     
    		Functor (void);
    		virtual ~Functor (void);
     
    		/* === Operator overloading === */
     
    		virtual std::string operator() (const std::string & parameters) const = 0;
    };
    L'objet fonction spécifique :

    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
     
    template < typename classType >
    class ClassFunctor : public Functor
    {
    	private:
    		/* === Private members === */
     
    		classType * m_object;
    		std::string (classType::* m_methodPtr)(const char *);
     
    		/* === Private constructors & destructor === */
     
    		ClassFunctor (classType * object, std::string (classType::* methodPtr)(const char *));
    		~ClassFunctor (void);
     
    	public:
     
    		/* === Public operator overloading === */
     
    		std::string operator() (const std::string & parameters) const;
     
    		/* === Public processing methods === */
     
    		static Functor * createFunctor (classType * object, std::string (classType::* methodPtr)(const char *));
    };
    Le collectionneur de commandes :

    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
     
    class Manager : public Singleton< Manager >
    {
    	friend class Singleton< Manager >;
     
    	private:
    		/* === Private typedef === */
     
    		typedef std::map< std::string, Functor * > FunctorsMap;
    		typedef std::pair< std::string, Functor * > FunctorsMapElement;
     
    		/* === Private members === */
     
    		FunctorsMap m_commands;
     
    	public:
    		/* === Public constructors & destructor === */
     
    		Manager (void);
    		~Manager (void);
     
    		/* === Public processing methods === */
     
    		void bindCommand (const std::string & funcName, Functor * function);
    		bool unbindCommand (const std::string & funcName);
     
    		void execute (const std::string & rawCommand) const;
    };
    Ensuite dans un objet où je veux lier une de ses méthodes à une commande console, je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    m_scriptsManager->bindCommand("version", Scripts::ClassFunctor< Core >::createFunctor(this, &Core::version));
    m_scriptsManager->bindCommand("exit", Scripts::ClassFunctor< Core >::createFunctor(this, &Core::shutdown));
    Voila. S'il y a des trucs qui frappent, les critiques sont les bienvenues.

  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
    Salut,
    Ce code est déjà d'un bon niveau

    Je me permets quelques remarques :
    => maintenant que tu sais comment on implémente Functor et ClassFunctor, tu peux utiliser leur version éprouvée : std::bind et std::function <std::string (std::string const&)> si tu as un compilateur C++11 (Visual 10 ou gcc > 4.??) ou sinon utilises les Boost.Bind et Boost.Function

    => si d'aventure tu ne v/peux pas utiliser ces bibliothèques, je te conseille le pimpl idiom pour redonner à Functor une sémantique de valeur ce qui me semble plus cohérent. Cela permettrait de le stocker par valeur dans ton conteneur. Sans oublier un smart pointer. Ce qui pourrait ressembler à
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    namespace
    {
       class FunctorImpl
       {
    // grosso modo ton ancien Functor
       };
     
     
       template < typename classType >
       class ClassFunctorImpl : public FunctorImpl
       {
    // grosso modo ton ancien ClassFunctor
       };
    }
     
    class Functor
    {
    public:
       std::string operator() (const std::string & parameters) const
       {
          return (*p_impl)(parameters);
       }
    private:
       std::unique_ptr<FunctorImpl> p_impl;
    };
     
    // ce qui permet de se passer de pointeurs : 
     
    class Manager : public Singleton< Manager >
    {
    	friend class Singleton< Manager >;
     
    	private:
    		/* === Private typedef === */
     
    		typedef std::map< std::string, Functor > FunctorsMap;
    		typedef std::pair< std::string, Functor > FunctorsMapElement;
     
    		/* === Private members === */
     
    		FunctorsMap m_commands;
     
    	public:
    		/* === Public constructors & destructor === */
     
    		Manager (void);
    		~Manager (void);
     
    		/* === Public processing methods === */
     
    		void bindCommand (const std::string & funcName, Functor const& function);
    		bool unbindCommand (const std::string & funcName);
     
    		void execute (const std::string & rawCommand) const;
    };
    => Je ne sais pas comment tu as écrit ta classe singleton mais manager devrait avoir son constructeur et son destructeur en privé.

    => Sur les classes manager : De la gestion des gestionnaires

    => Sur les singletons : Etes-vous atteint de Singletonite ?. Singletons, monostate et autres variables globales, cf ici.

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 70
    Points : 50
    Points
    50
    Par défaut
    Salut,

    Tout d'abord merci d'avoir pris la peine de lire le code.

    Alors effectivement je ne connaissais pas std::bind et std::function, je pense tout simplement y jeter un coup d'oeil. Quand j'ai compris un concept, je n'ai aucun problème à utiliser ce qui est déjà écris en standard. Pour Boost, j'ai cru comprendre qu'il faut rajouter une grosse bibliothèque supplémentaire. Et j'essaie d'éviter les dépendances qui ne se justifient pas pleinement.

    J'aime également l'idée du "pimpl idiom", parce que justement je me sentais un peu obligé d'utiliser des pointeurs. Dans mon cas, si je copie l'objet, je n'ai plus que le parent dans le container.

    Bien vu pour le constructeur en privé, c'est une faute d'inattention. C'est là ou votre article rentre en jeu. Je me rend compte effectivement, que j'ai trop de singleton inutile dans mon code. En plus, dans un soucis d'obliger un ordre de création, l'objet principal initie et stocke le pointeur de chacun des singletons que j'utilise... Du coup, je peux très facilement les retirer et rajouter quelques passages de paramètres. je vais quand même garder mon système de logs en Singleton, parce que je vois pas du tout comment faire proprement dans certain cas.

    Pour l'article sur les gestionnaires, j'ai cru comprendre que finalement on ne s'attardait que sur le nom donné à l'objet ? C'est vrai qu'ici, ce n'est pas vraiment un manager à proprement parler, c'est juste un objet qui stock, exécute ou retire des commandes. Et il ne doit rien faire d'autres.

    Sinon, quand je lis dans l'article qu'il faut éviter les gestionnaires, je vois mal comment remplacer ce genre de procédé ? Ca me semble naturel d'avoir un point centralisé pour éviter de se disperser.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Une ressource transverse dans laquelle on doit partager une ressource physiquement unique donne envie de faire un Singleton. Ce qui est glissant c'est qu'on finit par tout trouver transverse ou unique...par facilité
    Dans le cas précis du log, on a un peu l'impression de polluer le fonctionnel avec cette notion plutôt technico-technique...et j'avoue ne pas connaître d'autre solution...
    @3DArchi: que ferais-tu sur cette problématique?

  9. #9
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Citation Envoyé par le_ptit_lutin Voir le message
    Sinon, quand je lis dans l'article qu'il faut éviter les gestionnaires, je vois mal comment remplacer ce genre de procédé ? Ca me semble naturel d'avoir un point centralisé pour éviter de se disperser.
    Concernant cette dernière question, la réponse à mon sens est la suivante: décomposer la notion vague de "gestion de XXX" en un certain nombre de fonctionnalités bien définies, qui seront chacune une responsabilité confiée à une classe donnée. Par la suite utiliser la classe appropriée pour chaque fonctionnalité. Ainsi, on garde la simplicité.
    Dans ton cas, plutôt que Manager tu pourrais appeler ton type CommandRegistry, puisque c'est bien ce qu'il fait: il enregistre les commandes.
    Après on pourrait suggérer de remplacer la méthode execute par "find", et invoquer le foncteur retourné par find. En plus ça permettrait de changer la signature de l'opérateur() sans impacter le CommandRegistry, qui aurait toujours pour fonction de répertorier les commandes disponibles.

  10. #10
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 70
    Points : 50
    Points
    50
    Par défaut
    C'est une bonne idée !

    C'est vrai qu'au final, je ne donne qu'au "manager" la possibilité de d'exécuter les fonctions. Ce serait plus logique de pouvoir accéder à une fonction et en faire ce que l'on veut.

    Je pense qu'en fait je vais faire un tour de tout mes "managers" revoir un peut ce qu'ils font exactement et couper là ou il y a de trop et renommer un peu tout ça.

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,
    Citation Envoyé par le_ptit_lutin Voir le message
    Salut,

    Tout d'abord merci d'avoir pris la peine de lire le code.

    Alors effectivement je ne connaissais pas std::bind et std::function, je pense tout simplement y jeter un coup d'oeil. Quand j'ai compris un concept, je n'ai aucun problème à utiliser ce qui est déjà écris en standard. Pour Boost, j'ai cru comprendre qu'il faut rajouter une grosse bibliothèque supplémentaire. Et j'essaie d'éviter les dépendances qui ne se justifient pas pleinement.
    Je comprend ton point de vue, mais, s'agissant de boost, je n'y adhère absolument pas...

    L'ensemble de bibliothèques boost (car c'est ce dont il s'agit en réalité ) peut très clairement être considéré comme une extension de ce qu'offre la bibliothèque standard, la vitesse d'évolution en plus.

    Ce n'est en effet pas un hasard si des pans entiers de boost se retrouvent pour ainsi dire simplement "copiés / collés" dans certaines partie de la SL (enfin, dans TR1, par exemple ), ou qui ont fortement inspiré le comité pour la nouvelle norme

    De plus, boost::bind est ce que l'on appelle une bibliothèque "header only": il n'y a pas de bibliothèque (.lib ou .a, selon le système) à rajouter et, bien qu'il faudrait sans doute rechercher tous les fichiers impliqués, tu pourrais très bien te contenter de les rajouter à ton projet dans l'idée de ne plus revenir dessus par la suite

    Enfin, boost fait tellement office de "couteau suisse" du C++ que, tot ou tard, il te sera sans doute nécessaire d'utiliser l'une ou l'autre bibliothèque de boost dans ton projet, de préférence à l'une ou l'autre bibliothèque plus spécifique à un système donné (je pense, par exemple (mais de manière non exhaustive ), à boost::asio, boost::threads ou boost::serialization) afin d'assurer une meilleure portabilité et t'éviter de devoir "réinventer la roue"

    Je pense donc sincèrement que le fait de t'intéresser à boost est un investissement qui, à terme, ne peut que t'être bénéfique
    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 du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 70
    Points : 50
    Points
    50
    Par défaut
    Ah mais je n'ai pas dis que j'évite totalement Boost. C'est juste que je code en C++ depuis seulement un an et demi. Je commence seulement à être un peu à l'aise avec certain concept.

    Chaque fois que j'ai été confronté à Boost (que je ne connais absolument pas finalement), j'ai toujours eu l'impression que je devais ajouter la bibliothèque pour juste un "livre".

    Par exemple, les threads, j'ai préféré prendre la bibliothèque pthreads. Maintenant, je viens d'apprendre (grâce aux interventions du poste) que le nouveau standard c++11 ajoute les threads. Donc je vais retirer pthread de mon projet.

    Ce que je veux dire par là, c'est que j'ai pas encore trouvé un truc qui me ferait inclure Boost. A mon avis, je pense qu'il faut commencer un projet avec Boost depuis le début tout en le connaissant. Et c'est vrai que je n'ai pas été amené à découvrir de manière générale Boost.

    Je fais la comparaison avec PHP et un framework en fait. Ca me fait mal d'inclure un framework complet pour juste me servir d'une facette. Pour moi, soit on écrit avec le framework ou alors depuis 0. Maintenant je ne sais pas si on peux avoir le même raisonnement en C++.

  13. #13
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par le_ptit_lutin Voir le message
    Ah mais je n'ai pas dis que j'évite totalement Boost. C'est juste que je code en C++ depuis seulement un an et demi. Je commence seulement à être un peu à l'aise avec certain concept.

    Chaque fois que j'ai été confronté à Boost (que je ne connais absolument pas finalement), j'ai toujours eu l'impression que je devais ajouter la bibliothèque pour juste un "livre".

    Par exemple, les threads, j'ai préféré prendre la bibliothèque pthreads. Maintenant, je viens d'apprendre (grâce aux interventions du poste) que le nouveau standard c++11 ajoute les threads. Donc je vais retirer pthread de mon projet.

    Ce que je veux dire par là, c'est que j'ai pas encore trouvé un truc qui me ferait inclure Boost. A mon avis, je pense qu'il faut commencer un projet avec Boost depuis le début tout en le connaissant. Et c'est vrai que je n'ai pas été amené à découvrir de manière générale Boost.

    Je fais la comparaison avec PHP et un framework en fait. Ca me fait mal d'inclure un framework complet pour juste me servir d'une facette. Pour moi, soit on écrit avec le framework ou alors depuis 0. Maintenant je ne sais pas si on peux avoir le même raisonnement en C++.
    Encore une fois, je comprend ton point de vue, mais je n'y adhère (décidément ) pas.

    Tu ne dois pas voir boost comme un framework mais bien comme un ensemble de bibliothèques légères fournies, par hasard, par le meme fournisseur, et travaillant donc correctement de concert

    Il y a, par exemple, une différence flagrante entre boost (qui n'est qu'un ensemble de bibliothèques) et Qt (qui est véritablement un framework) du fait que tu restes totalement libre, lorsque tu décide d'utiliser une bibliothèque de boost, de travailler avec les autres bibliothèques de boost, ou pas, alors que, si tu décides d'utiliser une bibliothèque de Qt, quelle qu'elle soit, tu n'auras pas d'autre choix que d'utiliser les autres bibliothèques de Qt (je pense essentiellement à QtCore, par exemple ) pour le reste.

    Par exemple, sur le projet sur lequel je travaille pour l'instant, nous n'utilisons que boost::for_each et boost::bind pour une partie seulement de l'application et avec Qt pour ce qui est de la partie graphique (la distinction a, par chance, été suffisamment bien faite dés la conception pour que le coeur de l'application ne doive pas avoir recours au coeur de Qt ), et les tests unitaires n'utilisent meme pas boost::test

    D'un autre coté, je suis sur un projet personnel qui, jusqu'à présent, utilise boost::serialization et boost::test (pour les tests unitaires) parce que je l'ai décidé ainsi, et il n'est pas exclu que je décide, au fur et à mesure de l'avancée du projet, de rajouter boost::signals ou boost::thread, mais, ce ne sera rien d'autre qu'une décision fonctionnelle, parce que j'ai malgré tout la certitude que j'aurai à ma disposition des bibliothèques éprouvées et portables qui me faciliteront énormément la vie

    Quelque part, outre la qualité éprouvée des bibliothèques de boost, cette indépendance des bibliothèques de boost par rapport aux autres bibliothèques de boost est justement ce qu'il y a de remarquable et qui te permet de décider de les utiliser sans risque de te retrouver bloqué par rapport au choix d'une bibliothèque tierce supplémentaire quand le besoin s'en fait sentir
    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

  14. #14
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 70
    Points : 50
    Points
    50
    Par défaut
    Bon ben il est claire que je dois apprendre d'avantages sur comment Boost fonctionne et j'y penserai pour l'amélioration du projet.

    A ce stade, quelle est la différence entre std::bind/std::functor et leurs homologues de Boost?

  15. #15
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par le_ptit_lutin Voir le message
    Bon ben il est claire que je dois apprendre d'avantages sur comment Boost fonctionne et j'y penserai pour l'amélioration du projet.

    A ce stade, quelle est la différence entre std::bind/std::functor et leurs homologues de Boost?
    Pour faire simple, je dirais : leur disponibilité

    Les fonctions bind1st et bind2nd sont (sauf erreur) apparues dans le TR1, et passent dans la SL avec la nouvelle norme

    Ceci dit, il me semble que certaines possibilités proposées par boost::bind ont été rajoutées directement dans la SL avec la nouvelle norme (sans passer par TR1)

    Sur les compilateurs "récents" (comprend :implémentant déjà une partie de la nouvelle norme ) il n'y a donc pour ainsi dire aucune différence entre std::bind/std::functor et leurs homologues boost (les premiers étant à vrai dire le calque des deuxièmes ), alors que sur les compilateurs plus anciens, l'installation de boost peut s'avérer nécessaire et préférable à une mise à jour du compilateur
    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

  16. #16
    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
    Salut,
    Citation Envoyé par le_ptit_lutin Voir le message
    Alors effectivement je ne connaissais pas std::bind et std::function, je pense tout simplement y jeter un coup d'oeil. Quand j'ai compris un concept, je n'ai aucun problème à utiliser ce qui est déjà écris en standard.

    L'inverse peut être vrai : d'abord utiliser une bibliothèque ou une fonction de la STL en 'boîte noire' parce que c'est une notion trop complexe à ce moment de l'apprentissage. Puis ensuite quand on a progressé dans cette notion, regarder comment elle est mise en œuvre ou comment on pourrait soit même l'implémenter (mais juste dans un cadre d'apprentissage, on revient ensuite aux choses éprouvées et maintenues). A chacun sa façon d'apprendre.

    Citation Envoyé par le_ptit_lutin Voir le message
    J'aime également l'idée du "pimpl idiom", parce que justement je me sentais un peu obligé d'utiliser des pointeurs. Dans mon cas, si je copie l'objet, je n'ai plus que le parent dans le container.
    c'est exactement pour cela que je te le conseille. Cela redonne à ta classe Functor une sémantique de valeur pouvant être stockée par ... valeur, et copiée d'un conteneur à l'autre. Finalement, l'héritage (et le type erasure) est un détail d'implémentation du foncteur.
    Citation Envoyé par le_ptit_lutin Voir le message
    Pour l'article sur les gestionnaires, j'ai cru comprendre que finalement on ne s'attardait que sur le nom donné à l'objet ?
    Non. Le problème est relevé par le nom 'gestionnaire' mais le mot est le symptôme pas la cause. Celui ci est un mot valise sans définition précise. Or un des principes de base de l'architecture logicielle est de bien identifier les rôles et de les isoler les uns des autres. En général on colle le nom 'Gestionnaire' à une classe dont on a mal (ou pas) défini le rôle exact. Et ensuite, comme 'gérer' peut vouloir dire énormément de chose en fonction de chacun, on se retrouve à faire enfler cette classe en y mettant tout ce qu'on ne sait pas mettre ailleurs. Et on finit par se retrouver avec un objet omniscient, présent dans tout le code, obèse, instable et difficilement maintenable. 'Gestionnaire' est le parangon de ces objets sans sémantique bien identifiée ... et faut avouer qu'on le retrouve dans beaucoup d'architecture logicielle (et c'est aussi là qu'on retrouve le plus de bug et le plus d’appréhension chez celui dévolu à la correction/évolution)

    Citation Envoyé par le_ptit_lutin Voir le message
    Sinon, quand je lis dans l'article qu'il faut éviter les gestionnaires, je vois mal comment remplacer ce genre de procédé ? Ca me semble naturel d'avoir un point centralisé pour éviter de se disperser.
    En identifiant bien les rôles. En les séparant. Et du coup tu te rendras compte que chacune de tes classes n'a pas besoin d'accéder à l'ensemble de ces rôles mais seulement à un nombre limité et bien précis. Ceux-là deviennent naturellement des objets associés à des titres plus ou moins 'forts' selon la nature du lien.
    Cf la réponse de therwald
    Citation Envoyé par le_ptit_lutin Voir le message
    Chaque fois que j'ai été confronté à Boost (que je ne connais absolument pas finalement), j'ai toujours eu l'impression que je devais ajouter la bibliothèque pour juste un "livre".
    Tu peux renoncer à t'abonner à la bibliothèque de ton quartier parce que tu n'as besoin que d'un livre et l'acheter à la place (ou pire, l'écrire). A la fin de l'année, tu te retrouveras à avoir acheté (ou pire à avoir mal écrit) tous les livres de la bibliothèques un par un . Pas sur que ce soit rentable.
    Télécharge une fois pour toute l'ensemble des bibliothèques Boost. N'utilise dans ton projet que celle dont tu as besoin et sans plus te poser la question (comme cela été dit plus haut, ce n'est pas un framework mais un ensemble de bibliothèques indépendantes les unes des autres pour l'utilisateur).

    Citation Envoyé par therwald Voir le message
    @3DArchi: que ferais-tu sur cette problématique?
    Je vois au - deux types de logs:
    => celui utilisé en face de debug et de mise au point pendant le développement. Il peut potentiellement impacter toutes les classes de ton logiciel selon le moment et selon l'endroit où tu voudras placer ta loupe. Je n'ai pas de solution idéale pour cela. Je pense qu'une approche assez intéressante est la programmation orientée aspect. Celle-ci permet de bien séparer cet aspect de trace du code du logicielle. Je trouve cette approche assez adaptée à ce besoin. D'autant que cela permet d'injecter cet aspect qu'à des endroits bien précis en fonction de ce qui est recherché.

    => Un service de journalisation du logiciel permettant d'enregistrer certains évènements intéressants pour celui-ci (activation de certaines fonctions, évènements dans l'environnement, dans la configuration, certaines erreurs survenues, etc.). A ce moment, toutes les classes n'ont pas besoin de connaître ce service de journalisation. Dans chaque module (cette notion n'existe pas en C++ mais disons un ensemble de classe cohérentes entre elles et implémentant ensemble un certain service), il est probable que cette tâche sera dévolue à une seule des classes. Elle peut être construite alors en injectant le nécessaire pour transmettre les informations de log (boîtes aux lettres, etc...). Et elle peut s'abonner aux producteurs d'information intéressantes (çad, jugées nécessaire d'être loggé) vers les autres objets.
    On va retrouver les signaux et/ou des DPs observateurs (des choses sommes toutes assez similaires).

  17. #17
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 70
    Points : 50
    Points
    50
    Par défaut
    lol, j'ai la vague impression que si je dis encore un truc contre Boost, je vais entendre des "clics" de fusils à pompe.

    Plus sérieusement, je ne regrette pas d'avoir poser ma question sur le forum. J'ai appris pleins de trucs, je vous remercie tous

    Je vais revoir mes singletons, remplacer les threads, simplifier mes gestionnaires et découvrir Boost alors !

  18. #18
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Mais non, le fusil à pompe est une solution bien trop rapide et indolore !

    Plus sérieusement, avec un compilateur qui n'implémente ni C++11, ni le TR1, je considère l'utilisation de boost comme quasiment indispensable à l'écriture d'un bon code C++, et si je devais m'en passer, je commencerais probablement par redévelopper dans mon coin un sous ensemble de boost, moins bien foutu et plus bogué.

    Avec un compilateur C++11, boost devient tout de suite moins indispensable. Il reste très utile dans certains cas particuliers, selon le programme que l'on écrit. Mais il n'a plus autant ce côté incontournable.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

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

Discussions similaires

  1. Pointeur sur fonction membre avec parametre
    Par Glosialabolas dans le forum C++
    Réponses: 7
    Dernier message: 06/02/2006, 02h32
  2. Pointeur de fonction membre.
    Par fabone dans le forum C++
    Réponses: 2
    Dernier message: 18/01/2006, 13h18
  3. Pointeur de fonction membre
    Par legend666 dans le forum C++
    Réponses: 1
    Dernier message: 04/10/2005, 20h46
  4. Réponses: 10
    Dernier message: 03/02/2005, 13h09
  5. Réponses: 5
    Dernier message: 12/01/2005, 20h58

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