Diferencia entre func() y(* this).func() en C++
dispatch (4)
Con el nombre dependiente del tipo, puede ser diferente:
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
}
};
Estoy trabajando en el código de otra persona en C ++, y encontré una llamada extraña a cierta función
func()
.
Aquí hay un ejemplo:
if(condition)
func();
else
(*this).func();
¿Cuál es la diferencia entre
func()
y
(*this).func()
?
¿En qué casos la llamada a
func()
y
(*this).func()
ejecutará un código diferente?
En mi caso,
func()
no es una macro.
Es una función virtual en la clase base, con una implementación tanto en clase base como derivada, y sin
func()
libre
func()
.
El
if
se encuentra en un método en la clase base.
En realidad hay una diferencia, pero en un contexto muy no trivial. Considera este código:
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;
Ahora, si llamamos a
tf()
, la primera línea de
test::f
invocará la función libre
func
, mientras que la segunda línea llamará
derived::func
.
Es imposible distinguirlo del fragmento, pero posiblemente haya
dos
objetos invocables
llamados
func()
.
El
(*this).func();
se asegura de que se llame a la función miembro.
Un
objeto invocable
podría ser (por ejemplo) un
functor
o una expresión
lambda
:
functor
struct func_type
{
void operator()() const { /* do stuff */ }
};
func_type func; // called using func();
lambda
auto func = [](){ /* do stuff */ }; // called using func();
Por ejemplo:
#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();
}
Salida:
lambda function
member function
Otro caso cuando esas dos líneas llamarán a diferentes funciones:
#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();
}