2 votes

Y a-t-il des différences de nuance entre la syntaxe this->func() et func() ?

Si j'ai une classe avec une fonction virtuelle et aucune fonction libre, y a-t-il des différences entre this->func() y func()

class Base {
    virtual void A() { std::cout << "Base" << std::endl; };
    void B() { this->A(); };
    void C() { A(); };
};

class Derived : public Base {
    virtual void A() { std::cout << "Derived" << std::endl; };
    void B2() { this->A(); };
    void C2() { A(); };
};

Y a-t-il des différences dans l'exécution des méthodes B() y C() ? Qu'en est-il des méthodes B2() y C2() ?

7voto

templatetypedef Points 129554

Dans l'exemple que vous avez posté, il n'y a aucune différence entre les deux syntaxes. Elles sont totalement identiques.

Il y a deux cas où il y a une différence. Le premier est si vous avez une classe modèle qui hérite d'un type qui dépend d'un argument modèle. Par exemple :

template <typename T> class Base {
public:
    void doSomething() const {
       std::cout << "Do ALL the things!" << std::endl;
    }
};

template <typename T> class Derived: public Base<T> {
public:
    void doSomethingElse() const {
        doSomething();       // Error!
        this->doSomething(); // Okay
    }
};

Ici, puisque Derived<T> hérite du type Base<T> qui dépend d'un argument de modèle, la recherche de nom se fait en deux étapes. Si vous appelez doSomething en utilisant la syntaxe non qualifiée, alors le compilateur ne sait pas qu'il faut chercher dans Base<T> pour le trouver et signalera une erreur. Cependant, si vous dites this->doSomething() il sait que vous appelez une fonction membre et finira par comprendre qu'il est censé regarder dans le fichier Base<T> .

L'autre cas se présente si vous avez un objet local déclaré à l'intérieur de la fonction dont le nom est le même que celui d'une fonction membre. Par exemple :

class ThisIsSillyDontDoThisLikeSeriouslyDont {
public:
    void doSomething() const {
        std::cout << "Do ALL the things!" << std::endl;
    }

    void weirdFunction() const {
        auto doSomething = [] {
            std::cout << "I'm afraid there's nothing to be done" << std::endl;
        };

        doSomething();       // Calls the local function
        this->doSomething(); // Calls the member function
    }
};

Ce deuxième cas est si rare que je ne l'ai jamais vu, et j'irais même jusqu'à dire que c'est vraiment un mauvais style de codage.

En dehors de ces rares cas, il n'y a pas de différence entre appeler une fonction membre sur vous-même avec et sans this-> comme préfixe.

3voto

Brian Points 15388

En général, il n'y a pas de différence, puisque la norme exige un appel à une fonction membre de la forme A() pour être équivalent à (*this).A() . Voici quelques exemples où il y a une différence :

  1. S'il existe une déclaration de portée de bloc de A entonces A() appellera la fonction déclarée, alors que this->A() appellera toujours la fonction membre. Voir http://coliru.stacked-crooked.com/a/ea49916562bd4371
  2. Si A est un membre d'une classe de base dépendante, alors une tentative de l'appeler en tant que A() échouera ; this->A() est nécessaire pour reporter la recherche du nom au moment de l'instanciation.

0voto

Stephan Lechner Points 29375

Cppréférence concernant Fonctions membres non statiques indique qu'il existe une différence dans le contexte des définitions de modèles :

A l'intérieur du corps d'une fonction membre non statique de X, tout expression d'identification E (par exemple, un identificateur) qui se résout en un non-type membre non statique de X ou d'une classe de base de X, est transformée en une expression d'accès au membre (*this).E (sauf si elle fait déjà partie d'une fonction membre non statique). expression d'accès aux membres). Ceci ne se produit pas dans le contexte de la définition de définition de modèle, donc un nom doit être préfixé avec this-> explicitement pour devenir dépendant. devenir dépendant.

Ainsi, dans votre exemple, cela ne fait pas de différence, mais dans d'autres contextes, par exemple lors de la définition de modèles, c'est possible.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X