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 :

map<string, MaClasse<T>*> est ce possible ?


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 14
    Points : 16
    Points
    16
    Par défaut map<string, MaClasse<T>*> est ce possible ?
    Bonjour,

    J'aurai aimé savoir s'il est possible d'avoir un objet générique dans un map

    puisque l'initialisation se passe bien dans le constructeur mais lorsque je fait un boucle, ça plante :

    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
    #define TMPL template<class K>
    #define MYOBJ MaClasse<K>
    #define SELF MyClass<K>
     
    namespace toto{
     
    TMPL
    class MyClass 
    {
    	public:
    		DynamixData(void){m_map = new std::map<std::string, MYOBJ*>();}
    		~DynamixData(void){
    			std::map<std::string, MYOBJ*>::iterator iter;
         			for( iter = m_map->begin(); iter != m_map->end(); iter++ )
           				delete(iter->second);
    			delete(m_map);
    		}	
     
    	private:
    		std::map<std::string, MYOBJ*> *m_map;
    };//class MyClass
    };//namespace toto
    et voici ce que me dit le compilo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /MyClass.hpp:In destructor «toto::MyClass<K>::~MyClass()»:
    /MyClass.hpp:13: erreur: expected `;' before «iter»
    /MyClass.hpp:14: erreur: «iter» was not declared in this scope
    Avez-vous une idée?

    Merci d'avance pour votre aide.

    Julie .

  2. #2
    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
    Bonjour,
    Une question : pourquoi allouer dynamiquement ton map ?
    Une réponse : utilisation de typename lorsque le type est défini dans une classe template :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typename std::map<std::string, MYOBJ*>::iterator iter;
    [EDIT] : A titre personnel, j'aime pas trop ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define TMPL template<class K>
    #define MYOBJ MaClasse<K>
    #define SELF MyClass<K>
    Je trouve que ça rend la lecture du code confuse.

  3. #3
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 14
    Points : 16
    Points
    16
    Par défaut
    Merci pour ta réponse, elle m'a retirer une bonne 10en d'erreurs de compilo ;D

    Pourquoi l'allocation dynamique? parce que je préfère c'est tout, j'aime bien les pointeurs, ça me rassure

    Sinon pour les define, j'ajoute une ad-on à un logiciel et tout le code du logiciel est comme ça alors je suis le mouvement

  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
    Citation Envoyé par julie_n3k0 Voir le message
    Sinon pour les define, j'ajoute une ad-on à un logiciel et tout le code du logiciel est comme ça alors je suis le mouvement
    Ca je peux comprendre.
    Citation Envoyé par julie_n3k0 Voir le message
    Pourquoi l'allocation dynamique? parce que je préfère c'est tout, j'aime bien les pointeurs, ça me rassure
    Ca j'ai plus de mal Surtout pour un conteneur type map. Enfin, jettes un coup d'œil à cet article sur les pointeurs intelligents et le problème des pointeurs nus : Pointeurs intelligents, par Loïc Joly.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    En fait, l'utilisation des conteneurs sous la forme de pointeurs + gestion dynamique de la mémoire est totalement aberrante:

    1. La problématique de la gestion des pointeurs est complexe et peu sécurisante, allant du risque de manipuler un pointeur pointant vers une adresse mémoire ayant déjà été libérée à celui de provoquer une fuite mémoire, en passant par celui qui consiste à vouloir libérer de la mémoire deux fois (pour les principaux)
    2. Les conteneurs de la STL garantissent le respect du RAII, sont assignable et copiable de manière sécurisante et assurent eux-même la gestion de la mémoire de leur contenu... Passer par un pointeur pour les manipuler revient à "court-circuiter" ces comportement au prix de quelque chose qui ne sera souvent pas aussi efficace.
    3. En C++, il est très largement préférable (car bien plus sécurisant) de limiter l'utilisation aux cas pour lesquels il n'existe pas d'alternative:
      1. Les cas de polymorphismes (lorsque tu souhaites faire cohabiter deux types différents héritant d'une classe commune dans une collection en les considérant comme étant du type de la classe commune
      2. Les cas où, dans une relation contenant / contenu, tu souhaites disposer dans le contenu d'un membre représentant le contenant ou, de manière générale, tu souhaite disposer d'un membre qui te permette d'obtenir un autre objet de type similaire

    L'exemple type pour le 3-1 serait:
    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
    class Base
    {
        public:
            virtual ~Base();
            /* un tas de fonctions, virutelles ou non */
    };
    class Derivee1 : public Base
    {
        public:
            virtual ~Derivee1();
            /* soit des redéfinitions des fonctions virtuelles, soit quelques
             * ajoutées
             */
    };
    class Derivee2 : public Base
    {
        public:
            virtual ~Derivee2();
            /* soit des redéfinitions des fonctions virtuelles, soit quelques
             * ajoutées
             */
    };
    /* je veux faire cohabiter des Derivee1 et des Derivee2... 
     * mais je ne pourrai m'en servir que comme s'il s'agissait de Base
     */
    std::vector<Base*> tab;
    Pour le cas 3.2, les codes types seraient proches de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Contenant;
    class Contenu
    {
        private:
            Conetenant* parent_;
    };
    class Contenant
    {
        private:
            std::list<Contenu> children_;
    };
    ou de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class MaClass
    {
        private:
            MaClass  *next_;
    };
    Dans tous les autres cas, l'utilisation d'instances (MaClass obj), de références constantes (MaClass const & ou const MaClass &) ou non (MaClass &) s'avère très largement préférable et plus sécurisante

    Ceci dit, il faut savoir que, si tu as une classe template nommée MaClass, un MaClass<int> et un MaClass<AutreType> représenteront deux type strictement différents.

    Par conséquent, tu ne pourra pas faire passer un pointeur sur l'un pour un pointeur sur l'autre.

    Tu ne peux donc pas envisager d'écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template <typename T>
    class MaClass
    {
        /*...*/
    };
    int main()
    {
        MaClass<int> classI;
        MaClass<double> classD;
        MaClass</* que mettre, en sommes ? */> *ptr;
        ptr=&classI;
        ptr=&classD;
        return 0;
    }
    Pour que MaClass<int> et MaClass<AutreType> puissent être considérés comme "polymorphiquement compatibles", il faudrait que la classe modèle hérite d'une classe de base.

    Et, dans ce cas, tu devrais plutôt utiliser un pointeur de type... Mere

    Cela ressemblerait à un code proche de:
    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
    class Mere
    {
        public:
            virtual ~Mere();
    }
    template <class T>
    class MaClass
    {
        public:
            virtual ~MaClass();
    };
    /* ici, on peut travailler sous une forme proche de
     */
    int main()
    {
        std::vector<Mere*> tab; /* pourrait être n'importe quel conteneur STL */
        tab.push_back(new MaClass<int>);
        tab.push_back(new MaClass<TypePerso>);
        /* il ne faudra pas oublier de libérer la mémoire pour les pointeurs
         *
         * ...
         */
        return 0;
    }
    Il reste enfin un dernier cas dans lequel tu pourrait envisager de créer un conteneur de pointeur sur MaClass<>.

    C'est si le conteneur en question est... membre d'une classe template:
    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
    template<class T>
    struct MaClass{
        MaClass(T i):i(i){}
        T i;
    };
    template <class T>
    struct conteneur
    {
        /* par facilité uniquement */
        typedef MaClass<T> object;
        std::vector<object * > tab;
    };
    int main()
    {
      conteneur<int> c;
      c.tab.push_back(new MaClass<int>(2));
      cout<<c.tab[0]->i<<endl;
    }
    Tu remarquera que j'ai défini un alias de type object représentant MaClass<T> au sein de la classe dans laquelle j'ai déclaré le conteneur...

    C'est parce que, selon la norme en vigueur, >> ne possède que deux sémantiques: celle d'opérateur de flux et celle d'opérateur de rotation binaire.

    A l'heure actuelle, si tu voulais éviter de passer par un alias de type, le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<MaClass<T>> tab;
    sortirait sur une erreur de compilation car, pour fonctionner, il faudrait un espace entre le premier et le deuxième chevron fermant, sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<MaClass<T> > tab;
    (la prochaine norme que l'on attend avec impatience apporte une solution à cet état de fait )

    [EDIT]Un dernier commentaire en passant: les chaines de caractères ne représentent clairement pas le meilleur choix pour représenter la clé d'une map de par le temps nécessaire pour la comparaison...

    Si tu as le choix (comprend: s'il t'est possible de faire autrement) et que la vitesse d'exécution a de l'importance, préfère leur une valeur numérique entière, tu gagnera somme toutes énormément de temps sur une map contenant un grand nombre d'éléments
    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

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/10/2009, 10h38
  2. Trier une Map<Long, String> par rapport aux données
    Par zuzuu dans le forum Collection et Stream
    Réponses: 9
    Dernier message: 26/03/2009, 10h03
  3. map<int , vector <MaClasse> > MonNom;
    Par douls dans le forum SL & STL
    Réponses: 16
    Dernier message: 13/05/2008, 21h28
  4. Réponses: 2
    Dernier message: 01/05/2008, 16h13
  5. [STL]std::map<std::string, structure> Parcour...
    Par Zenol dans le forum SL & STL
    Réponses: 5
    Dernier message: 11/02/2006, 13h46

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