2010-03-08 27 views
53

Vorrei impostare un puntatore a funzione come membro di una classe che è un puntatore a un'altra funzione nella stessa classe. I motivi per cui lo sto facendo sono complicati.Funzione puntatore a funzione membro

In questo esempio, vorrei l'uscita di essere "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()) 
} 

Ma questo non riesce a compilare. Perché?

risposta

89

La sintassi è errata. Un puntatore membro è una categoria di tipi diversa da un puntatore ordinario. Il puntatore utente dovrà essere utilizzato insieme ad un oggetto della sua classe:

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 
} 

a.x non dice ancora su quello oggetto la funzione deve essere invitato. Dice solo che vuoi usare il puntatore memorizzato nell'oggetto a. Prependendo a un'altra volta l'operando di sinistra per l'operatore .* dirà al compilatore su quale oggetto chiamare la funzione.

+0

So che questo è vecchio, ma non capisco l'uso di '(a. * A.x)()'. Perché lo '(a. * X)()' non funziona? –

+0

@gau perché x non è nel campo di applicazione –

+1

@gau ho aggiunto Parens ora per renderlo più chiaro –

8

È necessario utilizzare un puntatore a una funzione membro, non solo un puntatore a una funzione.

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

int (*x)() non è un puntatore alla funzione membro. Un puntatore alla funzione membro è scritto in questo modo: int (A::*x)(void) = &A::f;.

5

Call member function on string command

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

Prestare attenzione alla (this->*func)(); e il modo per dichiarare il puntatore a funzione con il nome della classe void (A::*func)()

0

Mentre questo si basa sulle risposte sterline altrove in questa pagina, ho avuto un caso d'uso che non è stato completamente risolto da loro; per un vettore di puntatori a funzione effettuare le seguenti operazioni:

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

Qualcosa di simile è utile se si sta scrivendo un interprete di comandi con funzioni indicizzati che hanno bisogno di essere sposato con sintassi dei parametri e Aiutateci ecc Possibilmente anche utile nei menu.

Problemi correlati