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 :

[Debutant] Question sur un pointeur


Sujet :

C++

  1. #1
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut [Debutant] Question sur un pointeur
    Bonjour,

    je développe actuellement un client DCOM.
    Pour instancier un objet d'une interface, j'utilise la méthode suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER,IID_IOPCServer,(void**)&pServer);
    Je voulais savoir ce qu'étais
    (void**)&pServer
    Je suppose que c'est un pointeur, mais c'est un pointeur de quoi ?

    Merci pour vos réponses.
    ++

  2. #2
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Bonjour,
    c'est un pointeur sur un pointeur de type indéfini dans lequel tu peux lui passer n'importe quel type d'objet...

  3. #3
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Oui mais quand je regarde dans le MSDN, la définition de la fonction,

    STDAPI CoCreateInstance(

    REFCLSID rclsid,

    LPUNKNOWN pUnkOuter,

    DWORD dwClsContext,

    REFIID riid,

    LPVOID * ppv

    );
    LPVOID signifie alors qu'un pointeur vide est retourné ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    IOPCServeur *pServer
    (void**)&pServer)
    Cela signifie que le pointeur pServer est casté vers un type indéfini ? C ça ?
    Ne pourrais-je pas plutôt mettre (void)pServer ?

    Merci
    ++

  4. #4
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Par défaut
    salut,

    la fonction demande un LPVOID* (avec LPVOID ~ void*)

    or pServer est un IOPCServeur*. donc tu as besoin de passer en paramètre un pointeur sur ce pointeur (IOPCServeur**) => &pServer.
    pour respecter le type demandé par la fonction, tu castes (IOPCServeur**) en (void**) ou (LPVOID*)

    d'où (void**)&pServer

  5. #5
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Ok, je comprends.
    Donc si je résume pour m'assurer d'avoir bien compris.

    Dans le cas d'une fonction du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void fonctionExemple(int *argument);
    Je passe en paramètre de cette fonction un pointeur c'est à dire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int *pValeur=NULL;
    int valeur=0;
    pValeur=&valeur;
    fonctionExemple(pValeur);
    pValeur contient l'adresse de la variable valeur qui est passé en paramètre de la fonction fonctionExemple.

    Dans le cas d'un double pointeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void fonctionExemple(int **argument);
    Je dois passer en paramètre cette fos l'adresse du pointeur, ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int *pValeur;
    int valeur;
    pValeur=&valeur;
    fonctionExemple(&pValeur);
    C ça, j'ai bien compris ?
    Et ensuite, il suffit dans mon cas, de faire un cast pour récupérer le type demandé. C bien ça, n'est-ce pas ?

    ++

  6. #6
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Par défaut

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    sauf que là, tu n'auras pas besoin de "valeur", puisque là, c'est la fonction qui vera pointer ton pointeur sur une donnée.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    C donc ça l'interet du pointeur de pointeur ?

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Souvent, oui: C'est pour permettre à une fonction de modifier un pointeur.

    Quand ça ne sert pas à ça, ça peut aussi servir à un tableau de pointeurs...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Merci pour toute ces précisions, par contre dernière petite question à propos du cast d'un pointeur.

    J'aimerais comprendre un peu mieux le mécanisme.

    Supposons que je veuille copier deux pointeurs, s'ils sont de même type, j'aurais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int *val1;
    int *val2;
     
    val2=val1;
    Ca, je pense que tout le monde est d'accord;

    Par contre, si les 2 type sont différents je dois faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int val0;
    int *val1;
    char *val2;
     
    val2=(char*)val1;
    N'est-ce pas ?

    Mais val1 contient l'adresse d'une valeur pointée. val2 doit contenir l'adresse d'une autre valeur pointée, or en faisant (char*), mon adresse est convertie en pointeur, et du coup, au lieu de recopier dans val2, une adresse, je recopie une valeur, non ?
    Ne serait-il pas plus logique de faire:
    Bon en fait, je suis d'accord que non, parce que dans ce cas, c l'adresse qui est convertie en char, ce qui est n'importe quoi.
    Enfin, j'espère que vous comprenez là où ça me titille.

    C la-dessus que j'ai un peu de mal, je pense que ça se voit.


    Merci pour vos explications.
    ++

  11. #11
    Membre éprouvé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Par défaut
    Si tu veux copier une valeur pointée vers une autre :

    Si tu veux convertire un pointeur en un autre, ça ne modifiera pas le contenu de la mémoire, mais la manière dont elle est accédée et l'arithmétique des pointeurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    val2 = (char *)val1
     
    val2 = reinterpret_cast<char *>(val1)


    Et si tu veux convertire la valeur pointée - apparament l'objet de ta question :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    *val2 = (char)(*val1)
     
    *val2 = static_cast<char>(val1)

  12. #12
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Et si tu eux convertire la valeur pointée - apparament l'objet de ta question
    En fait, non, c'est plutôt le cast d'un pointeur.

    Si tu veux copier une valeur pointée vers une autre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    *ptr_dest = *ptr_src
    Ca je suis d'accord.

    Si tu veux convertire un pointeur en un autre, ça ne modifiera pas le contenu de la mémoire, mais la manière dont elle est accédée et l'arithmétique des pointeurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    val2 = (char *)val1
    val2 = reinterpret_cast<char *>(val1)
    En fait, c plutôt ça mon souci. Car si je fais (char *)val1, je devrais avoir un pointeur de char ? Non ?

  13. #13
    Membre éprouvé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Par défaut
    Citation Envoyé par etiennegaloup
    En fait, c plutôt ça mon souci. Car si je fais (char *)val1, je devrais avoir un pointeur de char ? Non ?
    Oui, mais dans certains cas c'est une opération dangeureuse, et parfois dépendante de la machine ...

    Il y a une différence entre caster une valeur et un pointeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /* avec int sur 32b */
    int entier = 0x70000000;
    float reel1, reel2;
    int *pi = &entier;
    float *pf1;
     
    pf1 = (float *)pi;
    reel1 = *pf1;
    reel2 = (float)*pi; // == (float)entier
    cout << reel1 << " " << reel2 << endl;

    Concernant un cast d'un int* vers un char*, ça pourrait bien se passer sur un PC, mais je me demande ce qu'il en est sur une machine en big-endian ...

  14. #14
    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 etiennegaloup
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int val0;
    int *val1;
    char *val2;
     
    val2=(char*)val1;
    N'est-ce pas ?

    Mais val1 contient l'adresse d'une valeur pointée. val2 doit contenir l'adresse d'une autre valeur pointée, or en faisant (char*), mon adresse est convertie en pointeur, et du coup, au lieu de recopier dans val2, une adresse, je recopie une valeur, non ?
    Je pense que tu te torture les méninges à cause d'un problème de vocabulaire. Pointeur est un nom de type. Une adresse est une quantité qui peut se représenter à l'aide d'une variable de type pointeur. Souvent, en parlant, on confond les deux.

    Pour te remontrer ton problème, je vais reformuler avec un autre type :

    pointeur <-> int <-> double
    adresse <-> entier naturel <-> nombre à virgule flottante

    Un entier naturel est une quantité qui peut se représenter à l'aide d'une variable de type int.

    Je vais reprendre tes propos : Quand tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double d = 3.14;
    int j = (int)d;
    Mais d contient un nombre à virgule flottante. i doit contenir un entier naturel, or en faisant (int), mon nombre à virgule flottante est convertie en int, et du coup, au lieu de recopier dans i, un entier naturel, je recopie un int, non ?
    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.

  15. #15
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par JolyLoic
    Je pense que tu te torture les méninges à cause d'un problème de vocabulaire. Pointeur est un nom de type. Une adresse est une quantité qui peut se représenter à l'aide d'une variable de type pointeur. Souvent, en parlant, on confond les deux.
    Je ne sais pas s'il a un problème de vocabulaire ou bien un problème de compréhension plus profond.

    Pour le vocabulaire, il y a trois choses:
    • un type, c'est un ensemble de valeurs;
    • un objet, c'est une région en mémoire qui doit être interprété comme étant d'un type donné; (une variable, c'est un objet qui a un nom)
    • une valeur, c'est le résultat de l'interprétation d'un ensemble de bits comme étant d'un type donné.


    Le langage courant utilise les noms de type pour ces trois choses et il faut faire attention au contexte pour savoir de quoi il est question. Parfois dans une même phrase le même mot va désigner une fois un objet et une fois une valeur.

    Les types pointeurs ne font qu'ajouter à la confusion potentielle. Les différentes valeurs possibles d'un type pointeur, ce sont les objets du type pointé. La manière dont sont habituellement représentées ces valeurs, c'est avec l'adresse de l'objet.

    Reprenons le code d'Étienne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int *val1;
    int *val2;
    En écrivant:on demande de copier la valeur de val1 dans val2. Donc les deux variables contiendront la même valeur, elles désigneront le même objet.

    En faisanton demande de copier la valeur de l'objet pointé par val1 dans l'objet pointé par val2. Donc les deux objets (rien n'indique qu'ils ont des noms) auront la même valeur, ils contiendront le même entier.

    Pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int *val1;
    char *val2;
    val2=(char*)val1;
    on de demande de copier dans val2, la valeur contenue dans val1 après l'avoir convertie en un pointeur vers char. Les deux variables désigneront des objets différents (un int dans un cas, un char dans l'autre) mais situés à la même adresse.

    Pournormalement le compilateur va râler: on lui demande de copier dans val2, qui est une variable de type pointeur vers char la valeur contenue dans val1 (qui est de type pointeur vers int) après l'avoir transformée en char. Copier un char dans un pointeur, c'est pas autorisé. (Et transformer un pointeur en char, c'est autorisé mais le résultat est généralement tout sauf utile).

  16. #16
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Il est clair que je me mélange pas mal.
    Je pense avoir compris les pointeurs.
    Mais là le cast de pointeur me titiller. Effectivement, je pense aussi que je me triture les méninges. J'ai une approche différente.
    Maintenant avec vos explications, c quand même bien plus clair.
    Je vous remercie tous pour vos explications.

    A bientôt pour de nouvelles aventures.
    ++

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

Discussions similaires

  1. [Debutant] Nouvelle question sur les pointeurs
    Par etiennegaloup dans le forum Débuter
    Réponses: 3
    Dernier message: 11/01/2006, 09h55
  2. [Debutant] Question sur la redéfinition de getPreferredSize
    Par etiennegaloup dans le forum Débuter
    Réponses: 1
    Dernier message: 23/09/2005, 20h02
  3. [Debutant] Question sur le system.out.print
    Par thom02 dans le forum Langage
    Réponses: 8
    Dernier message: 19/07/2005, 18h19
  4. questions sur les pointeurs
    Par Hyoga dans le forum C++
    Réponses: 17
    Dernier message: 08/01/2005, 23h25
  5. [debutant] Questions sur 1 futur projet
    Par cyrull22 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 28/04/2003, 21h49

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