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 :

Condition de check par spécialisation de templates


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut Condition de check par spécialisation de templates
    Bonjour à tous,

    Voilà je développe une bibliothèque dans laquelle j'ai une hiérarchie de classe héritante toutes de la class de base "Base".

    Pour abstraire un maximum de code, j'hérite également d'une classe template spécialisée "Check" qui implémente une méthode de vérification de certaines conditions (sorte de assert ou de programmation par contrat).

    La spécialisation à lieu selon un paramètre de template de type int (en réalité un enum) indiquant quel type de vérification doit être fait.

    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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #include <iostream>
     
    using namespace std;
     
    class Base {
      public:
        Base() : ptr(NULL), size(0), saved_index(0) {
        }
        void do_check() const {
          if (!check())
            cerr << "<< ERROR : check failed ! >>" << endl;
        }
      protected:
        virtual bool check() const = 0;
      protected:
        void *ptr;
        size_t size, saved_index;
    };
     
    typedef enum { ct_none, ct_no_nulls, ct_index_bounds, ct_memory_leaks } check_type_t;
     
    template<int check_type>
    class Check : public Base {
      protected:
        bool check() const;
    };
     
    template<>
    class Check<ct_none> : public Base {
      protected:
        bool check() const {
          return true;
        }
    };
     
    template<>
    class Check<ct_no_nulls> : public Base {
      protected:
        bool check() const {
          return ptr != NULL;
        }
    };
     
    template<>
    class Check<ct_index_bounds> : public Base {
      protected:
        bool check() const {
          return saved_index < size;
        }
    };
     
    template<>
    class Check<ct_memory_leaks> : public Base {
      protected:
        bool check() const {
          return ptr == NULL;
        }
    };
     
    class Child1 : public Check<ct_none> {
    };
     
    class Child2 : public Check<ct_no_nulls> {
    };
     
    class Child3 : public Check<ct_index_bounds>, Check<ct_memory_leaks> {
    };
     
    int main() {
      Child1 c1;
      Child2 c2;
      Child3 c3;
     
      c1.do_check();
      c2.do_check();
      //c3.do_check(); // là ça plante à la compilation
     
      return 0;
    }
    Cependant certaines classe héritées, doivent réaliser plusieurs vérifications, donc comment s'en sortir avec les templates ? La vraiment je ne vois pas ...

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Pour abstraire un maximum de code, j'hérite également d'une classe template spécialisée "Check" qui implémente une méthode de vérification de certaines conditions (sorte de assert ou de programmation par contrat).
    Tu peux peut-être regarder du côté de boost.concept_check.
    Sinon tu peux aussi prendre un compilateur qui implémente les Concepts de C++0x.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 58
    Par défaut
    A mon avis, il vaut mieux utiliser l'aggrégation que l'héritage pour faire tes checks.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2004
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 16
    Par défaut
    Tu n'a qu'a utiliser les différents bits de ton int check pour définir les types de vérifications à effectuer.

    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
    typedef enum {
    ct_none = 0x00,
    ct_no_nulls = 0x01,
    ct_index_bounds  = 0x02,
    ct_memory_leaks  = 0x04,
    //etc...
    } check_type_t
     
     
    template<int check_type>
    class Check : public Base {
      protected:
        bool check() const
        {
    	bool bCheckResult = true;
     
    	if(check_type & ct_no_nulls)
    	{
    		bCheckResult = bCheckResult && (ptr != NULL);
    	}
     
    	if(check_type & ct_index_bounds)
    	{
    		bCheckResult = bCheckResult && (saved_index < size);
    	}
     
     
    	if(check_type & ct_memory_leaks)
    	{
    		bCheckResult = bCheckResult && (ptr == NULL);
    	}
     
     
    	if(check_type & ct_index_bounds)
    	{
    		bCheckResult = bCheckResult && (saved_index < size);
    	}
     
    	return bCheckResult;
        }
    };
    du coup Child3 devient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class Child3 : public Check<ct_index_bounds|ct_memory_leaks> {
    };
    J'ai pas essayé mais ça devrait rouler...

  5. #5
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Citation Envoyé par XtremDev
    pas essayé mais ça devrait rouler...
    Merci XtremDev, et oui non seulement ça fonctionne parfaitement, mais en plus la série de "if" est évaluée à la compilation, ce qui fait que j'ai n fonction "check()" spécialisée contenant chacune uniquement le code nécessaire.

    Comme quoi, dès fois la solution la plus simple est la meilleure.

    Pendant que j'y suis, pour rester dans la simplicité, je me demandais si je ne pouvais pas retransformer un peu la collaboration entre classes. J'hésite entre plusieurs alternatives :

    1. Utiliser une fonction template au lieu d'une classe template "Check"
    2. Faire de l'héritage multiple pour découpler "Check" de "Base" (Check n'hériterais donc plus directement de "Base")
    3. Accéder à "Check" depuis "Base" via une délégation plutôt qu'un héritage

    Je vois bien les avantages de chacune des solutions, par contre pour les inconvénients j'ai du mal en à imaginer les futurs blocages probables si je devais adopter telle ou telle solution.

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Sauf qu'il n'y en a pas actuellement (juste un proto, pas utilisable pour du vrai code de production).
    C'est en effet en version alpha, c'est à dire que seulement partiellement implémenté.
    Mais je ne vois pas trop en quoi ça pose problème pour la production, si ce n'est que la dernière version par exemple est basée sur une branche non stable de GCC.

  7. #7
    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 : 50
    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
    Par défaut
    Citation Envoyé par loufoque
    Sinon tu peux aussi prendre un compilateur qui implémente les Concepts de C++0x.
    Sauf qu'il n'y en a pas actuellement (juste un proto, pas utilisable pour du vrai code de production). De toute façon, la syntaxe elle même n'est pas encore fixé (j'écris justement depuis une discussion au sujet d'un point de syntaxe, et il y a aussi eu d'autres détails de ce genre hier). C'est en cours de stabilisation, mais ce n'est pas fini.
    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.

Discussions similaires

  1. Réponses: 5
    Dernier message: 20/05/2012, 13h39
  2. Paramètre par défaut class templates
    Par Alp dans le forum C++
    Réponses: 2
    Dernier message: 26/02/2006, 02h06
  3. Réponses: 7
    Dernier message: 01/01/2006, 03h28
  4. [PHPMailer] Conditions de réutilisation par les pros
    Par Thierry8 dans le forum Bibliothèques et frameworks
    Réponses: 10
    Dernier message: 23/11/2005, 18h42
  5. [ JSP ][ MULTIBOX ] Struts Multibox checked par défaut
    Par maximus75 dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 15/06/2005, 17h30

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