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

Langage C++ Discussion :

Cast et réference de pointeur


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Par défaut Cast et réference de pointeur
    Bonjour à tous,

    J'ai le code suivant avec une classe Daughter qui dérive d'une classe Mother, et une fonction qui prend comme argument une référence de pointeur de Daughter. La fonction doit en effet changer l'adresse de l'objet Daughter passé en paramètre en fournissant une adresse de Daughter récupérée depuis un pool de Daughter:
    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 Mother
    {
    public:
    	Mother() {attrMother = 0;}
    private:
    	int attrMother;
    };
     
    class Daughter : public Mother
    {
    public:
    	Daughter() {attrDaughter = 1;}
    private:
    	int attrDaughter;
    };
     
    void refpointerfunction(Daughter*& param)
    {
    }
     
    int main()
    {
    	Mother* objM;
    	refpointerfunction((Daughter*)objM); //error C2664: 'refpointerfunction'*: impossible de convertir le paramètre 1 de 'Daughter *' en 'Daughter *&'
    	refpointerfunction((Daughter*&)objM); //ça passe
    }
    Vous allez surement me dire que mon code n'est propre, mais d'une part je dois utiliser un objet de type Mother pour une question de généricité du code, et d'autre part la fonction refpointerfunction() ne peut pas prendre un objet de type Mother* en paramètre ce qui serait l'idéal bien sur.
    Et je suis assuré que le type réel de objM est bien Daughter*, voilà pourquoi il n'y a pas de risque.

    Le truc que je comprends pas, c'est pourquoi le 1er appel me sort une erreur de compil. Quand j'ai une fonction qui prend en paramètre un int&, je lui passe un int et il n'y a aucun problème.
    Mais la je suis obligé de caster en référence de pointeur de Daughter, la cast en pointeur de Daughter ne suffit pas.

    Si vous pouviez éclairer ma lanterne, merci par avance.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Si je ne me trompe pas, une code comme celui-ci ne fonctionne pas non plus pour la même raison:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void foo(int&)
    {
    }
     
    int main()
    {
       foo(1);
    }
    On ne peut pas assigner une objet temporaire à une reférence non-constante(et le résultat d'un cast est un objet temporaire). D'ailleurs à propos de cast il vaudrait sans doute mieux utiliser un cast C++ien, non?

    EDIT: Pour modifier le pointeur objM, il faut passer par un pointeur de Daughter auquel on affecte objM(uniquement si la fonction refpointerfunction en a besoin, bien sûr!), que l'on passe comme paramètre à la fonction, puis qui est affecté à objM.
    Dernière modification par Invité ; 28/05/2010 à 17h46.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Par défaut
    Effectivement ton code ne va pas fonctionner, mais ce n'est pas pour la même raison si je ne m'abuse. Le "1" que tu passes en paramètre va faire que la fonction va créer temporairement une variable sur la pile dont la durée de vie sera celle de la fonction, ce qui est incompatible avec le passage par référence effectivement.

    Dans mon cas je passe un pointeur que j'ai déclaré avant l'appel de la fonction qui existe donc avant et qui existera après l'appel de la fonction, donc pas de problème de ce côté là.

    Oui c'est vrai pour la cast, je devrais utiliser le static_cast, plus propre. Mais la le but n'est pas forcément d'avoir un code propre (je sais c'est mal), mais vraiment de comprendre l'erreur de compil.

    Mon pointeur objM est bien modifié par le second appel qui compile lui, donc je n'ai pas de problème de ce coté là.
    J'aimerais vraiment comprendre pourquoi le 1er appel ne compile pas.

    Merci en tout cas.

  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
    Par défaut
    Salut,
    Pour l'explication, revenons à la source (c'est moi qui souligne ):
    Citation Envoyé par Norme (cast à la 'C')
    The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is a reference type, otherwise the result is an rvalue.
    Citation Envoyé par Norme (dynamic_cast<T>(v))
    If T is a pointer type, v shall be an rvalue of a pointer to complete class type, and the result is an rvalue of type T. If T is a reference type, v shall be an lvalue of a complete class type, and the result is an lvalue of the type referred to by T.
    Citation Envoyé par Norme (static_cast)
    The result of the expression static_cast<T>(v) is the result of converting the expression v to type T. If T is a reference type, the result is an lvalue; otherwise, the result is an rvalue.
    Moi, je m'y prendrais comme ça pour éviter toutes subtilités et ambigüités :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	Mother* objM;
            Daughter*objD = dynamic_cast<Daughter*>(objM);
    	refpointerfunction(objD);
            ObjM = ObjD;
    Bon, je me dois quand même de parler :
    -> du fait qu'un downcast est souvent révélateur de problème de design ;
    -> et que des pointeurs nus, c'est dangereux pour la santé.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Par défaut
    Ouccchh j'avais complétement oublié ce sujet .

    Merci beaucoup pour la réponse. En fait si je comprends bien, une fonction qui prend une référence comme argument attend une lvalue, et les opérateurs de cast renvoient des ravlue ?

    Je le mets en résolu du coup. Encore merci.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 23/01/2008, 12h36
  2. Réponses: 2
    Dernier message: 16/07/2007, 15h34
  3. Réponses: 9
    Dernier message: 14/01/2007, 16h40
  4. réferences et pointeurs
    Par Spacy_green dans le forum C++
    Réponses: 10
    Dernier message: 28/04/2006, 09h45
  5. Réponses: 12
    Dernier message: 31/12/2005, 16h01

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