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 void *


Sujet :

C++

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

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Points : 50
    Points
    50
    Par défaut Pointeur void *
    Bonjour,

    Après avoir cherché sans trouver, je me résolu a poster ce post. Je souhaite créer une classe "Liste" générique avec les fonction usuelle de gestion des liste. Les éléments de la liste sont d'un type indéfini. J'ai la méthode add(void *item):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int ListS::add(void *item)
    {
      current=malloc(sizeof(item)); 
    ...
    }
    où current est un pointeur vers l'élément courant de la liste (void *current) et la méthode getCurrent():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    void *ListS::getCurrent()
    {  return current;  }
    Comment faire pour récupérer la valeur de cet élément courant ? J'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int i=5;
    list->add(&i);
    printf("%d",*(list->getCurrent()));
    qui ne marche pas. J'ai aussi essayé (int) ... sans succès ...

    Merci pour votre aide.

    Christian

  2. #2
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Points : 68
    Points
    68
    Par défaut
    Salut,

    Tu a un pointeur (current) qui pointe sur une zone de la taille d'un pointeur (une adresse mémoire). Je pense que ce que tu veux plutôt faire c'est faire pointer ton pointeur (current) sur l'élément passer en paramètre à la méthode add(). Pour cela remplace la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    current=malloc(sizeof(item));
    par

    Tu essaye ensuite d'afficher la valeur pointée mais c'est un pointeur sur le type void donc je pense que printf() ne sait pas afficher un void. Utilise donc un pointeur intermédiaire de type int et transtype ton type void en int comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int i=5;
    list->add(&i);
    int* temp = (int*) list->getCurrent();
    printf("%d \n", *temp);

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Si en récupérant la valeur il te faut connaître son type pour l'utiliser, tourne toi vers les templates :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    template<class T>
    class Liste
    {
    public
        int add(T* item);
        T* getCurrent();
    private:
        T* current;
    };
     
    typedef List<int> TIntList;
    Tu aura alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    template<class T>
    int Liste<T>::add(T* item)
    {
        current = item;
    }
     
    template<class T>
    T* Liste<T>::getCurrent()
    {
        return current;
    }
    Puis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int i=5;
    TIntList* list = new TIntList();
    list->add(&i);
    int* temp = list->getCurrent();
    printf("%d \n", *temp);
    Ca évite ce genre de problème à l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int i=5;
    TIntList* list = new TIntList();
    list->add(&i);
    double* temp = list->getCurrent(); // erreur de compile
    printf("%d \n", *temp);
    L'inconvénient est qu'une liste ne contiendra que le même type d'objet. Dans ce cas, templarise juste la méthode pour laisser l'utilisateur transparent :
    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
     
    class Liste
    {
       int add(void* item);
       template<class T> T* getCurrent();
    };
     
    int Liste::add(void* item)
    {
       current = item;
    }
     
    template<class T> T* Liste::getCurrent()
    {
       return static_cast<T*>(current);
    }
    Et à l'utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int i=5;
    list->add(&i);
    int* temp = list->getCurrent<int>();
    printf("%d \n", *temp);
    Plus pratique
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  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
    Si ce n'est pas un exercice de cours, alors tourne toi directement vers la STL.
    Sinon, l'utilisation des template est la plus adéquate.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Mouais.
    La seconde solution proposée par mister est tout de même pas franchement terrible vu que cela ne permet pas de gérer le cycle de vie des objets de la liste. Et un objet incapable de détruire correctement les données qu'il contient ça n'est rien de moins qu'une hérésie! Ne parlons même pas des objets polymorphes...
    Une collection typée stockant ses objets par valeur est une solution beaucoup intéressante niveau apprentissage du langage. Si on veut vraiment une collection capable de stocker des objets d'un type non connu à la compilation la meilleure solution, celle qui fonctionnerait pour de vrai, pourrait être d'utiliser un std::vector de boost::any.

  6. #6
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    En quelques mots, voici ce qu'il faut que tu fasse si tu veux "réinventer la roue" (probablement pour un TP/TD/Examen/Autre, mais tu dois avoir tes raisons sinon tu utiliserais std::list ou similaire).

    1/ On ne programme pas en C/C++, ce langage n'existe pas. Soit en C, soit en C++. En C, void* est très utilisé faute de mieux, mais en C++ dans 99% des cas son utilisation est remplacée par celle des templates. Si tu ne connais pas, je t'invite à consulter l'un de nos cours C++, notamment http://bruce-eckel.developpez.com/li...on/ticpp2vol1/, pour y découvrir ce que sont les templates.

    2/ Les templates t'aideront pour rendre ta classe générique. Si tu n'as besoin que ce soient que des fonctions qui le soient et de stocker des éléments hétérogènes, alors tourne toi vers boost::any si tu ne connais pas les types des éléments susceptibles d'être mis dans la liste, boost::variant si tu sais exactement quels types d'éléments pourront y être mis.

    3/ En C++, on a les mots clés new et delete à la place de malloc, pour l'allocation et la désallocation de mémoire.

    4/ En C++, on a les flux standards : std::cout et std::cin à utiliser au lieu de printf, scanf & compagnie.

    Bref, tu es en C++ mais tu ne profites pas de sa puissance et de ses facilités, c'est bien dommage. Le cours dont j'ai donné le lien plus haut devrait t'aider à exploiter les facilités et la puissance du C++.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 89
    Points : 50
    Points
    50
    Par défaut
    Merci pour vos réponses très instructives.
    Je me forme (en autodidacte) et votre aide m'est précieuse.
    Christian

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Si après lecture du cours tu ne comprends pas trop le rapport entre void* et les templates, ou tout autre explication donnée ici, n'hésite pas à nous le signaler

Discussions similaires

  1. Pointeur, void ?
    Par Erast dans le forum Débuter
    Réponses: 6
    Dernier message: 16/04/2010, 00h33
  2. Réponses: 4
    Dernier message: 04/02/2009, 16h08
  3. Paramètres de PostMessage et pointeur void ?
    Par tintin72 dans le forum Windows
    Réponses: 8
    Dernier message: 17/06/2008, 13h36
  4. tableau de pointeurs void
    Par CerbeRGD dans le forum Débuter
    Réponses: 10
    Dernier message: 15/02/2008, 18h38
  5. Pointeur void *
    Par Atharendil dans le forum C
    Réponses: 6
    Dernier message: 04/05/2006, 09h53

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