Разница между func() и (* this).func() в С++
Я работаю над кодом другого кода на С++, и я нашел странный вызов определенной функции func()
. Вот пример:
if(condition)
func();
else
(*this).func();
В чем разница между func()
и (*this).func()
?
В каких случаях вызов func()
и (*this).func()
будет выполнять другой код?
В моем случае func()
не является макросом. Это виртуальная функция в базовом классе с реализацией как в базовом, так и в производном классе и без бесплатного func()
. if
находится в методе базового класса.
Ответы
Ответ 1
На самом деле это разница, но в очень нетривиальном контексте. Рассмотрим этот код:
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
.
Ответ 2
Из фрагмента невозможно определить, но возможно есть два вызываемых объекта func()
. (*this).func();
гарантирует, что вызывается функция-член.
Вызываемым объектом может быть (например) выражение 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
Ответ 3
Другой случай, когда эти две строки будут вызывать разные функции:
#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();
}
Ответ 4
С именем, зависящим от типа, оно может быть другим:
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
}
};
Демо