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 :

appel d'une méthode const sur un objet non const


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Points : 88
    Points
    88
    Par défaut appel d'une méthode const sur un objet non const
    Bonjour,

    il y a un truc que je n'arrive pas à comprendre, illustré par l'exemple suivant :

    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
    class A
    {
    public:
      class iterator {};
      class const_iterator {};
     
    public:
      iterator f() { return iterator(); }
      const_iterator f() const { return const_iterator(); }
    };
     
    int main()
    {
      A a;
     
      A::const_iterator it = a.f();
     
      return 0;
    }
    Quand je compile ce code, g++ me dit:

    Citation Envoyé par g++
    test_const.cpp: In function «int main()":
    test_const.cpp:16: erreur: conversion from «A::iterator" to non-scalar type «A::const_iterator" requested
    Je ne comprends pas pourquoi il ne trouve pas lui même la solution en appelant la méthode const. D'autant plus que c'est un problème que je n'ai pas avec les classes de la STL.

    La seule solution que j'ai trouvée est de passer par un "const A&" avant d'appeler f().

    Est-ce que vous pourriez m'expliquer ?

  2. #2
    Membre averti Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Points : 358
    Points
    358
    Par défaut
    Simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class iterator {};
    class const_iterator {};
    Ces 2 classes, n'ont aucun rapport.

    Etant differentes, tu ne peux stoquer un iterator sur un pointeur de const iterator, puisque le compilateur ne peut trouver de moyen de converter un objet de type iterator en objet de type const_iterator...

    La stl est faite d'une façon simple : const_iterator est une derivation d'iterator, ou le contraire ( je sais plus), donc tu peux convertir entre les 2 si necessaire( via des constructeurs explicites et operateurs = ).

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Points : 88
    Points
    88
    Par défaut
    je suis d'accord sur le fait qu'elles n'ont aucun rapport, on ne peut convertir un iterator en const_iterator. Par contre on peut appeler le méthode "const_iterator A::f() const" et ça résoudrait le problème.

    Pourquoi le compilateur ne "voit" pas cette solution ?

  4. #4
    Membre averti Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Points : 358
    Points
    358
    Par défaut
    Citation Envoyé par YéTeeh Voir le message
    je suis d'accord sur le fait qu'elles n'ont aucun rapport, on ne peut convertir un iterator en const_iterator. Par contre on peut appeler le méthode "const_iterator A::f() const" et ça résoudrait le problème.

    Pourquoi le compilateur ne "voit" pas cette solution ?
    Les compilateurs sont stupides, malheureusement ....

    Le compilateur decide de la fonction a utiliser, s'il y a surcharge, uniquement a partir des parametres ( comme f() est une fonction membre, la difference est faite entre la version const et non const,puisque l'instance de la class compte comme parametre, même s'il est caché ).

    Donc, a partir de ces informations, le compilateur choisira la fonction non const, si l'objet ne l'est pas.

    Apres seulement, il continue, et s'aperçoit que tu essaye d'affecter une class a un pointeur d'une autre.


    Pour info, c'est le même probleme que si tu cherchais a surcharger une fonction en changeant uniquement le type de retour, le compilateur n'aime pas.


    Bref, excessivement frustrant de temps en temps, mais il n'y a pas de solution directe ....

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Points : 88
    Points
    88
    Par défaut
    Citation Envoyé par Kujara Voir le message
    Pour info, c'est le même probleme que si tu cherchais a surcharger une fonction en changeant uniquement le type de retour, le compilateur n'aime pas.
    Au moins la surcharge uniquement sur le type de retour a le bon goût d'être interdite

    Merci beaucoup pour tes éclaircissements

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,
    Citation Envoyé par YéTeeh Voir le message
    Au moins la surcharge uniquement sur le type de retour a le bon goût d'être interdite
    Hé non, ce n'est pas aussi simple, malheureusement...

    En effet, il existe ce que l'on appelle "le retour co-variant" (je ne sais jamais s'il faut le trait d'union ou pas :$)

    Enfin, avec ou sans, le principe reste le même...On peut surcharger uniquement le type de retour, mais sous certaines conditions

    Imaginons un groupe de trois classes (A, B et C) dont deux dérivent de la troisième, que ce soit de manière directe ou indirecte ( D qui dérive de C qui dérive de A... mais ici, on oublie D ):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class A
    {
        /*...*/
    };
    class B:public A
    {
        /*...*/
    };
    class C:public A
    {
       /*...*/
    };
    Tu voudrais une classe DerC qui contienne et renvoie un C et une classe DerB qui contienne et renvoie un B...

    Hé bien, tu peux créer une interface Iface qui aura une méthode virtuelle Renvoie (vraisemblablement virtuelle pure, d'ailleurs) qui renverra... un A et dont dérivent DerB et DerC...

    La seule obligation, c'est de travailler soit avec un pointeur, soit avec une référence...

    Mais cela rend un code du genre 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
    25
    26
    27
     
    class Iface
    {
        public:
            virtual A& Renvoie()=0;
            /*...*/
    };
    class DerB:public Iface
    {
        public:
            DerB(const B& b);
            virtual ~DerB();
            virtual B& Renvoie(){return b;}
            /*...*/
        private:
            B b;
    }
    class DerC:public Iface
    {
        public:
            DerC(const C& c);
            virtual ~DerC();
            virtual C& Renvoie(){return c;}
            /*...*/
        private:
            C c;
    };
    tout à fait légal
    [EDIT]Evidemment, cela ne change rien à ce qui a été dit au sujet de const/non const

  7. #7
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    La surcharge sur le type de retour est interdite, pas particulierement par stupidite des compilateurs -- les algo existent, ca se fait en Ada par exemple -- mais parce que ca interagirait de maniere un peu forte avec d'autres choses: les conversions implicites.

    Le retour covariant n'est pas de la surcharge puisqu'il s'applique a des fonctions supplantees.

    A noter qu'il est possible de simuler de la surcharge sur le type de retour en utilisant les conversions implicites. On retourne une classe proxy qui a des operateurs de conversion implicite vers les types desires et qui font le vrai travail.

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    ton type const_iterator devrait pouvoir être construit à partir d'un iterator.
    Et hop, problème résolu.

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

Discussions similaires

  1. Appel d'une méthode sur une classe fille
    Par Tipha dans le forum C++
    Réponses: 5
    Dernier message: 29/05/2008, 14h23
  2. [script.aculo.us] Appel d'une méthode javascript sur le callback onUpdate
    Par thibane dans le forum Bibliothèques & Frameworks
    Réponses: 0
    Dernier message: 02/04/2008, 11h33
  3. Erreur sur l'appel d'une méthode
    Par Masmeta dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 01/02/2008, 14h41
  4. [POO] appel d'une méthode d'un autre fichier, le tout objet
    Par aaaaaaaa dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 13/07/2007, 18h43
  5. Réponses: 6
    Dernier message: 27/05/2005, 15h43

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