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 :

Utilisation de this


Sujet :

C++

  1. #1
    Membre actif Avatar de ttone
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    589
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 589
    Points : 203
    Points
    203
    Par défaut Utilisation de this
    Pourquoi est il plus propre d'utiliser MaClasse::methode() dans un prototype de MaClasse.class,
    plutôt que this->methode ?

    ps : ca marche aussi avec les arguments

  2. #2
    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
    Essaye ça et tu devrais avoir une piste pour comprendre:
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #include <iostream>
     
    class A
    {
    public:
       virtual void MaMethode()
       {
          std::cout<<"A::MaMethode"<<std::endl;
       }
       virtual void MaSecondeMethode()
       {
          std::cout<<"A::MaSecondeMethode"<<std::endl;
       }
     
       void MaisPourquoi()
       {
          std::cout<<"this->MaMethode()"<<std::endl;
          this->MaMethode();
          std::cout<<"A::MaSecondeMethode()"<<std::endl;
          A::MaSecondeMethode();
       }
     
    };
    class B :public A
    {
    public:
       virtual void MaMethode()
       {
          std::cout<<"B::MaMethode"<<std::endl;
       }
       virtual void MaSecondeMethode()
       {
          std::cout<<"B::MaSecondeMethode"<<std::endl;
       }
     
    };
     
    int main(int argc, char* argv[])
    {
       B b;
       b.MaisPourquoi();
       return 0;
    }

  3. #3
    Membre actif Avatar de ttone
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    589
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 589
    Points : 203
    Points
    203
    Par défaut
    Ca a donc un sens dans l'héritage.
    Uniquement?

  4. #4
    Membre averti Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Points : 323
    Points
    323
    Par défaut
    A priori je dirai que oui.
    Et je ne dirai pas que l'un est plus propre que l'autre.
    Ça dépend du comportement que tu veux. Si tu veux appeler la méthode du type réel de ta class (B), ou d'un de ces ancêtre spécifiquement.

  5. #5
    Membre actif
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Points : 284
    Points
    284
    Par défaut
    Et quelle est la différence entre ces 2 versions ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    this->maMethode()
    maMethode() // tout court
    J'ai l'impression que c'est juste une perte de lisibilité.

    Sinon, MaClasse::maMethode() n'est pas spécialement propre, puisqu'on désactive explicitement le polymorphisme.

  6. #6
    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
    Jette aussi un coup d'œil à ça.

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 700
    Points
    23 700
    Par défaut
    Citation Envoyé par Ulmo Voir le message
    Sinon, MaClasse::maMethode() n'est pas spécialement propre, puisqu'on désactive explicitement le polymorphisme.
    Non, mais il faut se souvenir que l'opérateur de portée est utile en cas d'ambigüité sur les noms de méthode.

    Le même programme qu'au-dessus mais avec une classe « Abis » identique à la classe « A » et de même génération :

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    #include <iostream>
     
    class A
    {
    public:
       virtual void MaMethode()
       {
          std::cout<<"A::MaMethode"<<std::endl;
       }
       virtual void MaSecondeMethode()
       {
          std::cout<<"A::MaSecondeMethode"<<std::endl;
       }
     
       void MaisPourquoi()
       {
          std::cout<<"A this->MaMethode()"<<std::endl;
          this->MaMethode();
          std::cout<<"A::MaSecondeMethode()"<<std::endl;
          A::MaSecondeMethode();
       }
     
    };
     
    class Abis
    {
    public:
       virtual void MaMethode()
       {
          std::cout<<"Abis::MaMethode"<<std::endl;
       }
       virtual void MaSecondeMethode()
       {
          std::cout<<"Abis::MaSecondeMethode"<<std::endl;
       }
     
       void MaisPourquoi()
       {
          std::cout<<"Abis this->MaMethode()"<<std::endl;
          this->MaMethode();
          std::cout<<"Abis::MaSecondeMethode()"<<std::endl;
          Abis::MaSecondeMethode();
       }
     
    };
     
    class B :public A , public Abis
    {
    public:
       virtual void MaMethode()
       {
          std::cout<<"B::MaMethode"<<std::endl;
       }
       virtual void MaSecondeMethode()
       {
          std::cout<<"B::MaSecondeMethode"<<std::endl;
       }
     
    };
     
    int main(int argc, char* argv[])
    {
       B b;
    // b.MaisPourquoi();  // Ambigü
       b.A::MaisPourquoi();
       b.Abis::MaisPourquoi();
       return 0;
    }

  8. #8
    Membre actif Avatar de ttone
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    589
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 589
    Points : 203
    Points
    203
    Par défaut
    Obsidian : dans le cas où il y a ambiguité, en effet !
    Mais je suis plutôt d'accord avec Ulmo : quand il n'y a pas d'ambiguité on perd en visibilité...

    J'utilisais automatiquement "this" auparavant, puis on m'a parlé de trucs qui rendent méfiant : pointage foireux, ou autre. C'est assez flou ce qu'on m'a dit.

  9. #9
    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
    Citation Envoyé par ttone Voir le message
    J'utilisais automatiquement "this" auparavant, puis on m'a parlé de trucs qui rendent méfiant : pointage foireux, ou autre. C'est assez flou ce qu'on m'a dit.
    Euh, ça c'est tout sauf une bonne excuse. Un pointage foireux fera un appel foireux quelque soit la façon de faire.

    Le plus important est de bien comprendre les différents mécanismes pour utiliser le plus adéquat. Je ne suis pas sûr qu'il y ait vraiment de réponse toute faite à ta question.

  10. #10
    Membre actif Avatar de ttone
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    589
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 589
    Points : 203
    Points
    203
    Par défaut
    Je reformule ma question avec plus de restriction:

    employer "this" dans une classe (ni abstraite, ni héritée, ni héritante, uniquement instanciée) est il mauvais ?

    Dans quels cas ?

    Est ce indispensable ?

    Faut il préférer : plutôt que ?

  11. #11
    Membre averti Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Points : 323
    Points
    323
    Par défaut
    employer "this" dans une classe (ni abstraite, ni héritée, ni héritante, uniquement instanciée) est il mauvais ?
    Non.

    Non.

    Faut il préférer :
    plutôt que
    ?
    Non car "MaClasse::" ne s'utilise que dans des cas particulier(cité au dessus), donc ce n'est pas une habitude a prendre.

    Mais dans la majorité des cas l'appel d'une fonction membre sans "this->" ni "MaClasse::" suffit, et clarifie la syntaxe. (enfin ça c'est mon opinion personnelle)

  12. #12
    Membre actif Avatar de ttone
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    589
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 589
    Points : 203
    Points
    203
    Par défaut
    Merci

    enfin ça c'est mon opinion personnelle
    : pléonasme...

  13. #13
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 700
    Points
    23 700
    Par défaut
    Citation Envoyé par Nogane Voir le message
    Non car "MaClasse::" ne s'utilise que dans des cas particulier(cité au dessus), donc ce n'est pas une habitude a prendre.

    Mais dans la majorité des cas l'appel d'une fonction membre sans "this->" ni "MaClasse::" suffit, et clarifie la syntaxe. (enfin ça c'est mon opinion personnelle)
    +1 et j'ajoute que ce n'est absolument pas une habitude à prendre, non seulement parce que ça ne sert à rien, mais parce que this désigne en soi un objet particulier. C'est idiot de le déréférencer si c'est pour se retrouver dans la situation initiale, et en plus, ça empêche l'utilisation de méthodes statiques !

    Le seul cas similaire où j'utilise le this (et, là encore, ça risque de faire pousser les hauts-cris chez certains) est quand je veux donner les mêmes noms aux membres de ma classe et aux arguments de ma méthode :

    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 Objet
    {
        public:
            void Reinitialise (int,int);
     
            int x;
            int y;
    };
     
    void
    Objet::Reinitialise (int x,int y)
    {
        this->x=x;
        this->y=y;
    }
    Évidemment, ça dépend beaucoup du contexte, et dans la plupart des autres, cela peut s'avérer plus chiant qu'autre chose mais, en l'occurence, on comprend très bien qu'il s'agit des mêmes données, et on voit très bien les membres à gauche du signe égal et les arguments à sa droite.

  14. #14
    Membre actif Avatar de ttone
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    589
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 589
    Points : 203
    Points
    203
    Par défaut
    Le seul cas similaire où j'utilise le this (et, là encore, ça risque de faire pousser les hauts-cris chez certains) est quand je veux donner les mêmes noms aux membres de ma classe et aux arguments de ma méthode
    A mes debuts sur C++, c'est exactement pour ca que j'utilisais "this", puis par extension je m'en servirai si il y a lieu dans les héritages.

    Je m'en suis en tous cas beaucoup servi pour tout emploi de méthode de MaClass dans les autres méthodes de MaClass, pour distinguer ainsi les méthodes statiques (qui ne possèdent alors aucun "préfixe"... et sont immédiatement repérable). Je perdrai cette (mauvaise) habitude (donc).
    Mais je ne comprends pas ce que tu désignes par "déréférencer" à propos de this...

  15. #15
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 700
    Points
    23 700
    Par défaut
    Citation Envoyé par ttone Voir le message
    Mais je ne comprends pas ce que tu désignes par "déréférencer" à propos de this...
    Je voulais dire que la référence à l'objet courant étant implicite, cela ne sert à rien d'aller explicitement invoquer un pointeur this pour retomber à coup sûr dans le contexte initial.

  16. #16
    screetch
    Invité(e)
    Par défaut
    je pense que la question de base etait plutot entre appeler this->methode() et A::methodeStatique() donc sans instance.

    en gros, faut il preferer les methodes statiques ?

  17. #17
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Citation Envoyé par screetch Voir le message
    je pense que la question de base etait plutot entre appeler this->methode() et A::methodeStatique() donc sans instance.

    en gros, faut il preferer les methodes statiques ?
    Quand on n'a pas besoin d'utiliser des variables/méthodes de la classe dans la fonction, autant le faire, ça permet de faire des pointeurs de fonctions simples, éviter d'appeler une fonction membre avec la classe en paramètre (même si le compilateur optimise ça normalement), ...

  18. #18
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 700
    Points
    23 700
    Par défaut
    Citation Envoyé par coyotte507 Voir le message
    Quand on n'a pas besoin d'utiliser des variables/méthodes de la classe dans la fonction, autant le faire, ça permet de faire des pointeurs de fonctions simples, éviter d'appeler une fonction membre avec la classe en paramètre (même si le compilateur optimise ça normalement), ...
    Si je ne me trompe pas, ce que tu dis n'est vrai que si l'on déclare la méthode statique. À l'appel, ca ne devrait pas compiler si ce n'en est pas une.

  19. #19
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    À l'appel, ca ne devrait pas compiler si ce n'en est pas une.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class A
    {
         public:
            //Ces fonctions n'accèdent pas aux membres
            void foo1() { cout << "hello world" << endl; }
            static void foo2() { cout << "hello world" << end; }
    };
    Les deux fonctions compilent, et je préfère déclarer comme foo2 et pas comme foo1, du fait des avantages que j'ai énuméré ci-dessus:

    • possibilité de faire un pointeur de fonction simple sur la fonction
    • pas besoin de déréférencer l'objet à chaque appel de la fonction, bien que le compilateur optimise sûrement ça


    Après c'est vrai que ce sont de maigres avantages qui ne servent pas souvent, et que c'est peut-être plus lisible d'omettre le mot-clé static.

    Bref, chacun fait comme il veut en connaissance de cause.

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Ce topic part un peu en sucette dû à la somme d'imprécisions qu'il recèle.

    Pour répondre à la question initiale: MaClasse::f() et this->f() ne sont pas équivalents.

    Lorsque l'on se situe dans le corps d'une fonction membre, chaque fonction appelée est implicitement appliquée à l'objet courant (si possible).
    Donc this->f() et f() sont équivalents.

    Notez que this->MaClasse::f() est une notation parfaitement correcte, c'est la forme explicite de l'appel ci-dessus.

    @coyotte: Je ne suis pas d'accord avec toi. Une fonction membre qui ne dépend pas des données d'un objet courant est par essence "statique" et dois être déclarée comme telle. Ce n'est pas un problème d'implémentation, mais de conception. Pour ne pas polluer le topic, on peut en parler ailleurs.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Utilisation de this
    Par supzero dans le forum Débuter avec Java
    Réponses: 8
    Dernier message: 22/02/2009, 22h14
  2. utilisation du this
    Par kenny.kev dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 08/04/2008, 14h36
  3. utilisation de this[]
    Par michpc dans le forum Flash
    Réponses: 2
    Dernier message: 01/02/2007, 12h59
  4. les classes et c# .. quand utiliser le "this" ?
    Par jgbid123 dans le forum Windows
    Réponses: 3
    Dernier message: 01/12/2006, 22h04
  5. [POO] Erreur lors de l'utilisation de $this en PHP5
    Par Ekimasu dans le forum Langage
    Réponses: 4
    Dernier message: 03/11/2006, 20h21

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