c++ - que - Puntero de función para función miembro
punteros y arreglos en c (5)
Me gustaría configurar un puntero a la función como miembro de una clase que sea un puntero a otra función en la misma clase. Las razones por las que estoy haciendo esto son complicadas.
En este ejemplo, me gustaría que la salida sea "1"
class A {
public:
int f();
int (*x)();
}
int A::f() {
return 1;
}
int main() {
A a;
a.x = a.f;
printf("%d/n",a.x())
}
Pero esto falla en la compilación. ¿Por qué?
La sintaxis es incorrecta. Un puntero de miembro es una categoría de tipo diferente de un puntero ordinario. El puntero miembro deberá usarse junto con un objeto de su clase:
class A {
public:
int f();
int (A::*x)(); // <- declare by saying what class it is a pointer to
};
int A::f() {
return 1;
}
int main() {
A a;
a.x = &A::f; // use the :: syntax
printf("%d/n",(a.*(a.x))()); // use together with an object of its class
}
ax
aún no dice en qué objeto se debe invocar la función. Simplemente dice que quiere usar el puntero almacenado en el objeto a
. El anteponer otra vez como el operando izquierdo al operador .*
Le indicará al compilador en qué objeto invocar la función.
Necesita usar un puntero a una función miembro, no solo un puntero a una función.
class A {
int f() { return 1; }
public:
int (A::*x)();
A() : x(&A::f) {}
};
int main() {
A a;
std::cout << (a.*a.x)();
return 0;
}
Si bien esto se basa en las respuestas de la libra en otro lugar de esta página, tuve un caso de uso que no fue completamente resuelto por ellos; para un vector de punteros a funciones haga lo siguiente:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
class A{
public:
typedef vector<int> (A::*AFunc)(int I1,int I2);
vector<AFunc> FuncList;
inline int Subtract(int I1,int I2){return I1-I2;};
inline int Add(int I1,int I2){return I1+I2;};
...
void Populate();
void ExecuteAll();
};
void A::Populate(){
FuncList.push_back(&A::Subtract);
FuncList.push_back(&A::Add);
...
}
void A::ExecuteAll(){
int In1=1,In2=2,Out=0;
for(size_t FuncId=0;FuncId<FuncList.size();FuncId++){
Out=(this->*FuncList[FuncId])(In1,In2);
printf("Function %ld output %d/n",FuncId,Out);
}
}
int main(){
A Demo;
Demo.Populate();
Demo.ExecuteAll();
return 0;
}
Algo como esto es útil si está escribiendo un intérprete de comandos con funciones indexadas que necesitan casarse con sintaxis de parámetros y consejos de ayuda, etc. Posiblemente también sea útil en los menús.
Llamar a la función miembro en el comando de cadena
#include <iostream>
#include <string>
class A
{
public:
void call();
private:
void printH();
void command(std::string a, std::string b, void (A::*func)());
};
void A::printH()
{
std::cout<< "H/n";
}
void A::call()
{
command("a","a", &A::printH);
}
void A::command(std::string a, std::string b, void (A::*func)())
{
if(a == b)
{
(this->*func)();
}
}
int main()
{
A a;
a.call();
return 0;
}
Preste atención a (this->*func)();
y la forma de declarar el puntero de función con el nombre de clase void (A::*func)()
int (*x)()
no es un puntero a la función miembro. Un puntero a la función miembro se escribe así: int (A::*x)(void) = &A::f;
.