Forum Programmation.c++ Un dictionnaire ... comment faire ?

Posté par  (site web personnel) .
Étiquettes : aucune
0
10
oct.
2005
Bonjour ...
J'ai un projet qui utilise pleins d'objets ... ces objets peuvent être reliés entre eux par une méthode commune a chaque objet. De même d'un objet on peut obtenur ses enfants par les méthodes suivantes:

void objet::attach(char* name, objet* child);
objet* objet::detach(char* name);
void objet::delete(char* name);

le paramètre name est le nom de l'enfant tel qu'il sera vu par le parent.
la méthode attach, crée une référence sur l'objet child
la méthode detach supprime cette référence et retourne un pointeur sur l'objet en question
la méthode delete supprime l'enfant.

Mais je n'ai aucune idée sur la manière d'implémenter ces fonctions ... sachant qu'un parent a un nombre indéterminé d'enfants.
j'aimerais aussi si possible avoir une méthode qui retourne une liste de tous les enfants avec leur identifiant (char* name)

Pouvez-vous m'indiquer une solution ou alors un endroit ou je pourrais trouver de la doc appropriée ... j'ai tenté d'utiliser std::map mais je n'ai pas compris grand chose

merci
Mildred
  • # Commencer par le début ...

    Posté par  . Évalué à 2.

    À mon avis tu devrais commencer par lire la doc sur std::string (aka std::basic_string < char >) pour éviter de perdre/méprendre des const char* dans la nature. Et puis pour le reste de la stl, std::map comprise, lire les passages sur les itérateurs.
    My2c
  • # std::map

    Posté par  (site web personnel) . Évalué à 2.

    std::map est très simple. C'est un objet qui lie une clé, dont le type est donné par toi, à un objet dont le type est donné par toi.

    avant de te montrer un exemple, chacune des clé doit être unique.

    supposons que j'ai décidé de créer un logiciel pour ranger mes nombreux cd audios.

    alors dans mon petit programme, j'ai créer un objet audio :
    class Audio
    {
    public:
    Audio(int n, std::string m) : nombre_piste(n), nom_cd(m) { }

    private:
    int nomre_piste;
    std::string nom_cd;
    }

    et sur chacun de mes cd j'ai collé une étiquette avec un numéro qui lui doit absolument être unique.

    maintenant je vais utiliser un dictionnaire du genre

    map<int numero, Audio *pointeur> cdaudio;

    cdaudio[1547] = new Audio(5, "Les trois petits cochons");
    cdaudio[107] = new Audio(1, "Pas-Star Academy");
    ...

    et puis quand tu veux récupérer un cd tu fais ;
    Audio p = cdaudio[1547];
    ...
    • [^] # Re: std::map

      Posté par  (site web personnel) . Évalué à 2.

      Merci ... j'avais a peu près compris ca ...
      mais que se passe-t-il si cdaudio[107] n'existe pas ..?

      En fait, il me faudrait pouvoir tester si une clef existe pour ne pas écraser une clef existante ...
      Et en plus, j'aimerais que si la clef existe, créer automatiquement un nom unique (ajouter un nombre derrière par exemple) et le retourner ...

      sinon, j'aimerais bien voir une doc sur la STL mais où puis-je la trouver ... complète et en francais de préférence ...
      Surtout que je débute en C++

      Merci

      PS: si je préfère char* à std::string c'est que je vais devoir interfacer mon application avec une application C ... donc qui utilise char*
      mais c'est vrai, comment libère-t-il la mémoire après ?... Je trouve toujours difficile de réfléchir sur les pointeurs ...
      • [^] # Re: std::map

        Posté par  . Évalué à 0.

        c'est simple, tu fais un destructeur, un operateur de recopie ( sinon tu vas avoir des belles blagues ) des contructeurs qui vont bien... tu fais ton bouleau quoi...

        l'autre solution - celle du glandeur - consisterait a les stocker sous forme de std::string et les restituer sous forme de char *

        l'objet c'est tres bien si on passe par une periode de conception avant ( comme tout type de prog, mais en objet, c'est VITAL, sinon on se retrouve a convertire des date en string pour les reconvertir en date la ligne suivante... )

        n'oublie pas si tu fais des new ( ou malloc Arggg ) en c++ il y a de fortes probabilité ( a peu pres 100% ) qu'il y ait un delete ( ou free ) qui va avec...

        n'oublie pas la redéfinition d'operateur, et la non duplication des valeurs pointées par la recopie par défaut.

        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

      • [^] # Re: std::map

        Posté par  (site web personnel) . Évalué à 2.

        http://www.sgi.com/tech/stl/(...)

        j'ai pas mieux comme doc.

        alors que se passe-t-il si cdaudio[107] n'existe pas ?
        eh bien, l'objet map crée automatiquement une clé "107" liée avec un pointeur vers un objet Audio nul, donc si je ne me trompe pas... et bien sûr pour l'exemple que j'ai donné ;-)... en faisant cdaudio[107] on aura en retour : (Audio*)0. Maintenant si c'est pas un pointeur et disons qu'on avait

        map<int numero, Audio objet> cdaudio;

        alors il aurait créé l'objet Audio() en utilisant le constructeur par défaut.

        pour éviter ce fonctionnement, tu peux bien sûr tester au préalable si la clé existe en utilisant la méthode :

        iterator find(const key_type& k)

        et pour ça je te laisse lire la doc.


        Concernant ta préférence du char*, je vois pas trop ce que tu veux dire mais il doit bien y avoir moyen d'utiliser le std::string.
        • [^] # Re: std::map

          Posté par  (site web personnel) . Évalué à 1.

          Merci pour la doc ... Mais je n'arrive pas a l'utiliser ni a bien la comprendre.
          
          Par exemple, j'aimerais bien savoir sur quelle page je peux trouver toutes les méthodes associées à un iterator ... ou alors la description précise de la méthode find().
          Pour la méthode find, j'ai trouvé un lien vers AssociativeContainer.html qui explique un peu plus en détail. Mais il y a alors une référence à a.end() ... et je n'ai pas réussi a en trouver la description.
          
          
          Peut être que j'ai les yeux bouchés ... mais j'ai vraimment du mal a utiliser cette doc.
          
          
          Sinon, finalkement je vais utiliser les std::string ... c'est sans doute plus simple.
          
          
          Voila ce que j'ai fait :
          J'espère ne pas avoir fait trop d'erreurs ... c'est surtout pour le childred.erase(name) que je ne suis pas sure. Il ne faut pas qu'il supprime l'objet référencé.
          
          class object {
          public:
          	std::string	attach(const std::string &name, WoT3D::object* object){
          		if(!this->children.count(name)){
          			// la clef n'existe pas
          			this->children[name]=object;
          			return name;
          		}else{
          			int i = 1;
          			while(this->children.count(name << i)){
          				i++;
          			}
          			this->children[name << i]=object;
          			return (name << i);
          		}
          	}
          		WoT3D::object*	detach(const std::string &name){
          		if(!this->children.count(name))
          			return NULL;
          		WoT3D::object*	object_returned;
          		object_returned = this->children[name];
          		this->children.erase(name);
          		return object_returned;
          	}
          	void		remove(const std::string &name){
          		if(this->children.count(name)){
          			delete this->children[name];
          			this->children.erase(name);
          		}
          	}
          	// ...
          private:
          	std::map<std::string, WoT3D::object*> children;
          };
          
          Merci tout de même.
          • [^] # Re: std::map

            Posté par  (site web personnel) . Évalué à 1.

            c'est vrai que la doc n'est pas toujours très claire... j'ai fait une très rapide recherche sur internet et j'ai trouvé un petit tutoriel en pdf : http://www.moteurprog.com/index.php?url=tuto_affiche.php&ID_tut(...)

            je ne sais pas si ça peux t'aider sinon tu peux faire une recherche sur google avec "doc stl c++" ou quelque chose du genre.

            Parce que je pense qu'avant de se lancer dans la programmation, il serait intéressant que tu te penches sur les classes de base de la stl comme les conteneurs, les itérateurs et tout ça.

            Et attention, à plusieurs reprises dans ton code, j'ai vu "name << i"... je dit peut-être des bêtises mais je suis presque sûr que va remplacer le contenu de name par la valeur de i ou du moins ajouter i dans la chaîne de caractères, je sais pas ce que tu comptes faire mais attention car ton "name" sera modifié car tu as mis un & dans les arguments de la fonction ;-)
            • [^] # Re: std::map

              Posté par  (site web personnel) . Évalué à 1.

              Merci ... En fait, après mon post, j'ai remarqué ca et j'ai changé ...
              	}else{
              		int i = 1;
              		char buf[32];
              		sprintf(buf, "%d", i);
              		while(this->children.count(name + buf)){
              			i++;
              			sprintf(buf, "%d", i);
              		}
              		this->children[name + buf]=object;
              		return (name + buf);
              	}
              
              Je pense que c'est plus correct ... J'avais du mettre l'opérateur << car on le rencontre pour les entrées/sorties standard ... mais + a l'air de fonctionner aussi bien sans modifier la chaîne.
              
              Merci de ton aide précieuse.
              

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.