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 :

Template, et accesseur complexe


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut Template, et accesseur complexe
    Bonjour!
    J'ai quelques problèmes dont je ne trouve nul solution, c'est pourquoi je vous appelle à l'aide.^^
    Tout d'abord au niveau des templates:
    y a t'il un moyen de restreindre le choix du compilo au moment de remplacer les templates? C'est à dire qu'en faite j'ai :
    template <typename T>
    void Fct(T param){...}
    mais en faite je voudrais que le compilo décide entre un type string, double ou bool uniquement, c'est possible avec les template ou je dois faire pour les multitude de fct similaire que j'ai à coder, des surdefinition ?

    Ensuite un second problème me pertube, bien qu'en faite je lai plus ou moins résolu:
    J'ai fait un système de variable simple, je stock les variables dans des map<string(nom de la variable), bool( ou double, string suivant le type de la variable)>
    accesoirement j'ai une map< string(nom de variable), enum( qui défini Chaine, Nombre, Bool)> qui permet un referencement rapide de toutes les variables et de leur type.
    Enfin tous ça pour dire(et encore c'est simplifié) que sur ceux, j'ai problème d'accesseur!
    Il faudrait que je fasse une fct DonneVariable() qui renvoie soit du bool, soit du double, du string suivant le type de la variable! ( template marche pas car de toutes façon il y aurait 2 return de type différent de celui de la template).
    Ma solution c'est du #define DonneVariable() [et la on peut retourner des types différents car c'est pas une fct]

    le truc, c'est que c'est assez moche dutiliser un define pour faire une fct, nan ?
    si quelqu'un à un idée...

    Merci d'avance, Scheb

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour Scheb

    le compilo décide entre un type string, double ou bool uniquement
    Déjà, premier problème !
    Le compilateur ne décide pas du type à mettre dans un template. C'est l'utilisateur de la classe template qui utilise le type qu'il souhaite.

    Il existe qu'une seule façon de limiter les types utilisés dans un template : bien documenter sa classe pour que les utilisateurs sachent comment l'utiliser correctement !

    Pour le second problème, si j'ai bien compris, tu as plusieurs map (une pour chaque type). Le plus simple dans ce cas est d'écrire une fonction pour chaque map :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    string getStringVariable(string nom);
    bool getBoolVariable(string nom);
    int getIntVariable(string nom);
    Par contre, c'est pas très joli et pratique : ça suppose de connaitre le type lors de la création et lors de la récupération de la variable.

    Sinon, c'est un problème classique. Regarde du coté de boost:variant ou de Qt::QVariant.


    PS: DEFINE ? C'est encore utilisé en dehors des protections des en-têtes ?
    Il vaut mieux les éviter, ça peut poser des problèmes. Il vaut mieux utiliser des templates.

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    1) Tu peux t'inspirer de Boost.TypeTraits pour vérifier si les paramètres templates fournis sont bien du type attendu. Mais si tu n'as que 3 types, je suis plus partisan de 3 fonctions, mais il faudrait en savoir plus pour vraiment juger.

    le truc, c'est que c'est assez moche dutiliser un define pour faire une fct, nan ?
    Le truc, c'est que tout ta conception est moche. C'est plus que bancal de lister/trier toutes les variables ainsi. Sinon, il reste boost::variant comme l'a dit gbdivers
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    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,
    Comme dit, le premier peut se régler à coup de Boost.Type trait et Boost.Static Assert :
    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
    #include<iostream>
    #include <string>
    #include <boost/static_assert.hpp>
     #include <boost/type_traits.hpp>
     
    template<class T>
    void a_function(T t_)
    {
        BOOST_STATIC_ASSERT((
                boost::is_same<T,bool>::value
            ||  boost::is_same<T,int>::value
            ||  boost::is_convertible<T,std::string>::value
        ));
        std::cout<<t_<<"\n";
    }
     
    int main()
    {
        std::cout<<std::boolalpha;
        a_function(true);
        a_function(1);
        a_function(std::string("aa"));
        a_function("aa"); // erreur const char* != std::string => boost::is_convertible à la place de is_same pour traiter ce cas.
        a_function(42.0); // erreur
        return 0;
    }
    Cependant, comme le dit David, si tu dois n'avoir que 3 instances et que cela ne va pas changer, j'aurais aussi tendance à préférer 3 fonctions surchargées pour bool, double et std::string.

    Pour le second, il y a probablement un petit problème de conception. Cependant, tu peux soit utiliser un boost::variant, soit un visiteur :
    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
    #include<iostream>
    #include <string>
     
    struct visiteur
    {
        virtual void do_it(double )=0;
        virtual void do_it(bool )=0;
        virtual void do_it(std::string )=0;
        protected:
        ~visiteur(){}
    };
     
    enum e_type
    {
        e_bool,
        e_string,
        e_double
    };
     
    void a_function(e_type e_, visiteur &v_)
    {
        switch(e_)
        {
            case e_bool:
            v_.do_it(true);
            break;
            case e_string:
                v_.do_it(std::string("coucou"));
            break;
            case e_double :
            v_.do_it(1.0);
            break;
        }
    }
     
    struct mon_visiteur : public visiteur
    {
        virtual void do_it(double )
        {
            std::cout<<"un double\n";
        }
        virtual void do_it(bool )
        {
            std::cout<<"un bool\n";
        }
        virtual void do_it(std::string )
        {
            std::cout<<"un string\n";
        }
    };
     
    int main()
    {
        mon_visiteur v;
        a_function(e_bool,v);
        a_function(e_string,v);
        a_function(e_double,v);
        return 0;
    }

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    ok merci beaucoup pour vos réponse, je pense pouvoir me débrouiller maintenant

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Toutefois, je cherche toujours un moyen de demander la valeur sans connaitre son type (que ce Boost.variant, une union, les systeme de map ou n'importe qu'elle autres conceptions).
    Mais je me demande si ça n'est pas impossible (du moins trop difficile) car à ce moment là il faudrait une fonction comme ceci;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    xxx DonneVariable(nom)
    {
    if(IsBool())
    return DonneVarBool(nom);
     
    if(IsDouble())
    return DonneVarDouble(nom);
     
    if(IsChaine())
    return DonneVarChaine(nom);
    }
    car xxx ne pourrait jamais convenir au trois en ême temps (même une template) donc je vois pas et ça m'ennui car ce serai bien plus ergonomique pour la suite...

  7. #7
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Le point est que pour récupérer la valeur il faudra forcément que quelqu'un (le programmeur, une fonction, ...) connaisse son type car ta variable tu vas la récupérer dans une variable typée.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Hum mais c'est à dire que oui, enfin quand tu dis qu'une fct doit connaitre le type, est ce que les fct IsBool() que j'ai mis dans l'exemple suffisent ?

    Ce serait l'interet de pas avoir a spécifier, même si on peut utiliser un intermédiaire:
    #define DonneVariable( var ) DonneValeur(var, DonneType( var ))
    (oups j'oubliais que vous aimez pas les define^^)

    En tout cas merci de m'aider.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Bon, j'ai voulu tout remettre en ordre car ça commencé à être dûr à suivre. J'ai fait un code qui synthetise le probleme ce qui peut bien aider à me comprendre^^.

    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
    #ifndef CCMS_HPP_INCLUDED
    #define CCMS_HPP_INCLUDED
     
    #include <map>
    #include <string>
     
    using namespace std;
     
    union UnionVar // c'est la valeur de la variable
    {
    	char var_chaine;
    	bool var_bool;
    };
     
    class Tata // ça m'énerve les gens fan de toto
    {
    	private:
     
    	map<string, UnionVar> map_var; //la fameuse map ! string continent le nom de la variable
     
    	public:
     
    	//jvais faire des déclarations à la vollé pour eviter un .cpp
     
    	//je mets les mutateurs à titre explicatif
    	void Mutateur(const char *variable, bool valeur)
    	{
    		map_var[variable] = valeur;
    	}
     
    	void Mutateur(const char *variable, char valeur)
    	{
    		map_var[variable] = valeur;
    	}
     
     
    	///!\\ et là survient le probleme, l'accesseurs
    	bool AccesseurBool(const char *variable)
    	{
    		return map_var[variable];
    	}
     
    	char AccesseurChaine(const char *variable)
    	{
    		return map_var[variable];
    	}
     
    	/**
            et c'est là que j'embète tout le monde!
            Je voudrais savoir, afin d'obtenir une meilleur ergonomie et facilité d'utilisation (bref du chipotage),
            si il est possible d'avoir un accesseur global grâce à je ne sais quelle technique et pas 2 de chaque type,
            c'est à dire;
     
            boolOUchar Accesseur(const char *variable)
            {
                    return map_var[variable];
            }
     
            ?*/
     
     
    };
     
    #endif // CCMS_HPP_INCLUDED
    voili voilou^^

  10. #10
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Je pense qu'un boost::variant serait ici très adapté, comme dit précedemment !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    typedef boost::variant<char, bool> my_variant;
    // ...
    map<string, my_variant> map_var;

  11. #11
    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
    boost.any est ton ami (ou boost.Variant si le nombre de type est limité - cf F.A.Q.) :
    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
    #include <iostream>
    #include <string>
    #include <map>
    #include <exception>
    #include <boost/any.hpp>
     
    class Tata
    {
    	private:
     
    	std::map<std::string, boost::any> map_var;
     
    	public:
    	template<class T>
    	void Mutateur(const char *variable, T valeur)
    	{
    		map_var[variable] = valeur;
    	}
     
     
    	boost::any Accesseur(const char *variable)
    	{
    		return map_var[variable];
    	}
     
    };
     
    int main()
    {
       Tata t;
       t.Mutateur("bool",true);
       t.Mutateur("char",'c');
       std::cout<<std::boolalpha<<"t[bool] = "<<
             boost::any_cast<bool>(t.Accesseur("bool")) // accès typé avec type connu
          <<"\n";
       std::cout<<std::boolalpha<<"t[char] = "<<boost::any_cast<char>(t.Accesseur("char"))<<"\n";
       try{// erreur :
          std::cout<<std::boolalpha<<"t[char] = "<<
                   boost::any_cast<bool>(t.Accesseur("char")) // si ce n'est pas le bon, ça lève une exception
               <<"\n";
       }
       catch(std::exception const &e)
       {
          std::cout<<"bad cast : "<<e.what()<<"\n";
       }
       Tata t2;
       boost::any val = t.Accesseur("bool");
       t2.Mutateur("trucmuche",val); // cependant, on peut garder des boost.any si on se 'fout' du type effectif
       std::cout<<std::boolalpha<<"t2[trucmuche] = "<<boost::any_cast<bool>(t2.Accesseur("trucmuche"))<<"\n";
       return 0;
    }

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    merci de vos réponses mais ..., justement l'intêret c'est que l'ont ne connaisse pas le type (la tu spécifie avec "boost::any_cast<bool>" le type qui doit être connue....ce qui peut être egalement réalisable avec les templates par ailleurs. Et d'ailleur à ce moment je chipoterai pas et je me contenterai de la fct exemple "AccesseurBool("mavariable");").
    Alors pour connaitre le type on m'a parlé de visiteur ou toutes sortes de choses, soit, le but est tout de même d'arrive à la fin à avoir à appeller simplement "Accesseur("mavariable");", ce que je pense de plus en plus, impossible...
    Voilà, maintenant si c'est impossible, il faut me le dire, et je devrais me résigner à specifier à chaque fois le type de ma fonction

    PS: accessoirement, vous m'avez tout de même fait connaître boost et effectivement, je pense qu'il va vite devenir un fidéle outil pour moi

  13. #13
    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
    Je vais répondre à ta question par un autre question : Supposes que tu as une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    magic_type_finder Accesseur(std::string const&);
    Que vas-tu faire du résultat de l'appel Accesseur("ma_variable") ?

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Je vais répondre à ta question par un autre question : Supposes que tu as une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    magic_type_finder Accesseur(std::string const&);
    Que vas-tu faire du résultat de l'appel Accesseur("ma_variable") ?
    Disons que cela n'a plus de rapport avec un quelquonque projet, c'est plûtot pour savoir si c'est possible.
    Cependant ce systeme de variable peut m'être utile dans un projet de moteur de jeu, où je me sert de class comme objet (heritant d'une class objetBase). Pendant le deroulement du programme, les objets doivent communiquer entre eux, ("le missile touche le mur -> mur.vie -= 10;") et je ne peux pas déclarer toute les variables que je vais utiliser dans ObjetBase (insensé). C'est pourquoi j'ai besoin d'un systeme de communication de variable Simple entre objet.

    Voilà je sais pas si ça peut t'aider, mais c'est un exemple d'utilisation. Le faite est que pour le moment j'utilise des fonctions du type "AccesseurBool(..)" et ça marche très bien certe, seulement, plus tard je vais ouvrir le moteur au "tout public", même des gens qui connaitrons peut le C++ pourront s'en servir (c'est pour ça que je voulais éviter qu'ils tombent sur "AccesseurBool(..)/Chaine(..)" "hein !?", mais plûtot un simple "Accesseur(..);")

    Maintenant c'est peut être impossible, je vais pas vous faire perdre de temps, hein ?

    PS: on va me crier; "erreur de conception !!!" Non non, ben sinon j'utilise AccesseurBool()!

  15. #15
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Je pense que tu n'as pas compris la question de 3DArchi.
    Quand il te demandais "Que vas-tu faire du résultat de l'appel Accesseur("ma_variable") ?", je pense qu'il ne parlait pas du projet dans lequel tu voulais faire cela.
    Il voulait savoir (ou plus précisément te faire réfléchir) ce tu fais de la variable retournée par Accesseur().

    Imagine que tu as 2 classes : A et B. A demande à B la valeur d'une variable nommée V.
    A priori, si A demande ça à B, c'est que A veut faire quelque chose de V. Donc A connait le type de V. Sinon elle ne saurait pas quoi faire avec V (et n'aurait aucune raison de demander V).

    Pour prendre l'exemple de ton jeu, imagine que tu doives écrire une fonction et on te donne une variable dont tu connais pas le type. Tu peux faire quoi avec cette variable ?
    A priori, rien !

    "je ne peux pas déclarer toute les variables que je vais utiliser dans ObjetBase (insensé)"
    En fait, si.
    Ou plus précisément, tu vas déclarer tes variables dans des classes différentes qui seront liées entre elles (héritage, composition...) Et lorsque tu demanderas à un objet (dont tu connais le type) de te transmettre une variable (dont tu connaitras le type aussi), tu sauras quoi en faire

  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,
    Comme le dit gbdivers, savoir ce que tu fais avec le retour de la fonction est aussi déterminant pour savoir comment construire ta fonction. Si lorsque tu appelles Accesseur("bidule"), tu sais que tu va manipuler un bool, char, etc... alors une version générique avec un boost::any_cast dans la fonction peut être appropriée. Si tu te fous du type retour mais que tu continues à le manipuler comme chose alors un retour de type boost::any suffit.
    En d'autres termes, pour savoir si c'est possible, tu dois reformuler ta question plus contextuellement.
    De plus, si ton problème est l'échange de message entre différents objets tout en gardant une certaine abstraction, ce n'est peut être pas tout à fait la bonne option que tu as prise. Je ne connais pas le design de ton projet, mais peut être peux-tu jeter un coup d'oeil au DP Command.

  17. #17
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Effectivement, c'est logique
    Une utilisation classique serai une comparaison:
    if( Accesseur("mavar") < 100) // un nombre
    forcément l'utilisateur sera qu'il lui faut un nombre et pas une chaîne comme type de var (seulement ne pas
    devoir spécifier le genre aurait été plus ergonomique -> chipotage hein^^)

  18. #18
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Citation Envoyé par Scheb Voir le message
    Effectivement, c'est logique
    Une utilisation classique serai une comparaison:
    if( Accesseur("mavar") < 100) // un nombre
    forcément l'utilisateur sera qu'il lui faut un nombre et pas une chaîne comme type de var (seulement ne pas
    devoir spécifier le genre aurait été plus ergonomique -> chipotage hein^^)
    Tu vois tes objets en tant que gros tas de variable. En faisant ainsi, tu exposes l'intérieur de ta classe (la mécanique interne) alors que l'un des but de la POO est l'encapsulation. Cela signifie que les classes offrent des services via leurs fonctions membres publiques, services que l'on peut appeler. Comment c'est traité à l'intérieur, ON S'EN FOUT. Un utilisateur de la classe n'a PAS à connaitre les détails de ta classe. S'il les connait, c'est que ta conception est foireuse.

    Exemple avec une classe représentant les nombres complexes.
    Elle doit offrir accès à la partie réelle, imaginaire, à l'argument et au module du nombre, à son conjugé, ...

    Selon la représentation choisie (algébrique [a+ib] ou exponentielle [r*exp(i*théta)] ) certaines fonction seront immédiates. Renvoyer la partie réelle dans une représentation algébrique, c'est renvoyer a alors qu'il faut calculer le module (sqrt(a^2+b^2)). A l'inverse avec une représentation sous forme expo, le module est trivial, pas la partie réelle.

    En tant qu'utilisateur d'une telle classe, je veux être sûr des résultats des fonctions, l'état interne de la classe m'importe pas. Tu pourrais même envisager de passer dynamiquement d'une représentation à un autre, comment ferais tu alors si tu expose tes variables membres ?

    Pour moi, il te manque un cours de conception OO. A ce titre, je ne peux que t'engager à regarder ce blog et en particulier cela
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  19. #19
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Ok merci, jvais voir si jpeux refaire ma conception...

  20. #20
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Bonjour tous

    Citation Envoyé par gbdivers Voir le message
    Il existe qu'une seule façon de limiter les types utilisés dans un template : bien documenter sa classe pour que les utilisateurs sachent comment l'utiliser correctement !
    Tout à fait ! Une astuce consiste à utilise des typedef qui rendent l'utilisation du template transparente et à ne documenter que ce type (côté utilisateur).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    typedef MonTruc<std::string> MonTrucString;
    typedef MonTruc<double> MonTrucDouble;
    typedef MonTruc<bool> MonTrucBool;
    Par exemple. Ce n'est en rien une protection, mais ça place une petite barrière "psychologique" et indique clairement que c'est toi qui choisis quels types sont bons à utiliser avec le template.
    Find me on github

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 4
    Dernier message: 23/07/2011, 08h35
  2. Réponses: 7
    Dernier message: 07/04/2003, 09h35
  3. appliquer plusieurs templates
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 04/04/2003, 16h26
  4. template match="node() mais pas text()"
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/03/2003, 10h52
  5. [XSLT] template
    Par demo dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 09/09/2002, 11h31

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