Разница между func () и (*this).func() в C++


Я работаю над чужим кодом на C++, и я нашел странный вызов определенной функции func(). Вот пример:

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

в чем разница между func() и (*this).func()?

Какие бывают случаи, когда звонят func() и (*this).func() будет выполнять другой код?

в моем случае, func() это не макро. Это виртуальная функция в базовом классе, с реализацией как в базовом, так и в производном классе, и без свободного func(). Этот if находится в методе в базовом классе.

4 59

4 ответа:

на самом деле есть разница, но в очень нетривиальном контексте. Рассмотрим этот код:

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;

теперь, если мы называем t.f() первая строка test::f вызовет свободную функцию func, в то время как вторая линия будет назвать derived::func.

невозможно сказать из фрагмента, но, возможно, есть двавызываемые объекты под названием func(). Элемент (*this).func(); убедитесь, что вызывается функция-член.

A callable объект может быть (например)functor или lambda выражение:

функтор

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

func_type func; // called using func();

лямда -

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

для пример:

#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();
}

выход:

lambda function
member function

другой случай, когда эти две строки будут вызывать разные функции:

#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();
}

С типом зависимого имени, это может быть по-другому:

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
    }
};

демо