59 votes

Différence entre func() et (*this).func() en C++.

Je travaille sur le code de quelqu'un d'autre en C++, et j'ai trouvé un appel bizarre à une certaine fonction. func() . Voici un exemple :

if(condition)
    func();
else
    (*this).func();

Quelle est la différence entre func() y (*this).func() ?

Quels sont les cas où l'appel à func() y (*this).func() exécutera un code différent ?

Dans mon cas, func() n'est pas une macro. C'est une fonction virtuelle dans la classe de base, avec une implémentation à la fois dans la classe de base et dans la classe dérivée, et pas de fonction libre. func() . Le site if se trouve dans une méthode de la classe de base.

47voto

lisyarus Points 9611

Il y a effectivement une différence, mais dans un contexte très différent. Considérez ce code :

void func ( )
{
    std::cout << "Free function" << std::endl;
}

template <typename Derived>
struct test : Derived
{
    void f ( )
    {
        func(); // 1
        this->func(); // 2
    }
};

struct derived
{
    void func ( )
    {
        std::cout << "Method" << std::endl;
    }
};

test<derived> t;

Maintenant, si nous appelons t.f() la première ligne de test::f invoquera la fonction libre func tandis que la deuxième ligne appellera derived::func .

31voto

Galik Points 522

Il est impossible de le dire à partir de l'extrait, mais il est possible qu'il y ait des éléments suivants deux objets appelables appelé func() . Le site (*this).func(); s'assure que la fonction membre est appelée.

A objet appelable pourrait être (par exemple) un functor ou un lambda expression :

foncteur

struct func_type
{
    void operator()() const { /* do stuff */ }
};

func_type func; // called using func();

lambda

auto func = [](){ /* do stuff */ }; // called using func();

Par exemple :

#include <iostream>

class A
{
public:

    // member 
    void func() { std::cout << "member function" << '\n'; }

    void other()
    {
        // lambda
        auto func = [](){ std::cout << "lambda function" << '\n'; };

        func(); // calls lambda

        (*this).func(); // calls member
    }
};

int main()
{
    A a;
    a.other();
}

Sortie :

lambda function
member function

17voto

Revolver_Ocelot Points 4502

Un autre cas où ces deux lignes appellent des fonctions différentes :

#include <iostream>

namespace B
{ void foo() { std::cout << "namespace\n"; } }

struct A { 
  void foo() { std::cout << "member\n"; }

  void bar()
  {
      using B::foo;
      foo();
      (*this).foo();
  }
};

int main () 
{
    A a;
    a.bar();
}

12voto

Jarod42 Points 15729

Avec un nom dépendant du type, cela peut être différent :

void func() { std::cout << "::func()\n"; }

struct S {
    void func() const { std::cout << "S::func()\n"; }
};

template <typename T>
struct C : T
{
    void foo() const {
        func();         // Call ::func
        (*this).func(); // Call S::func
    }
};

Démo

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