2010-08-25 2 views
6

Ho una classe A che contiene funzioni membro foo() e bar() che restituiscono un puntatore alla classe B. Come posso dichiarare un array contenente le funzioni foo e bar come membro variabile in classe A? E come posso chiamare le funzioni attraverso l'array?C++: Matrice di puntatori a funzioni membro

risposta

17

La funzione sintassi puntatore membro è ReturnType (Class::*)(ParameterTypes...), quindi es .:

typedef B* (A::*MemFuncPtr)(); // readability 
MemFuncPtr mfs[] = { &A::foo, &A::bar }; // declaring and initializing the array 
B* bptr1 = (pointerToA->*mfs[0])(); // call A::foo() through pointer to A 
B* bptr2 = (instanceOfA.*mfs[0])(); // call A::foo() through instance of A 

Vedi esempio this InformIT article per ulteriori dettagli sui puntatori ai membri.

Si potrebbe anche voler guardare in Boost.Bind e Boost.Function (o loro equivalenti TR1), che permettono di associare opaquely Stati-funzione-puntatori a un'istanza:

typedef boost::function<B*()> BoundMemFunc; 
A instanceOfA; 
BoundMemFunc mfs[] = { 
    boost::bind(&A::foo, &instanceOfA), 
    boost::bind(&A::bar, &instanceOfA) 
}; 
B* bptr = mfs[0](); // call A::foo() on instanceOfA 

Per utilizzare tale matrice come membro, si noti che non è possibile inizializzare gli array utilizzando l'elenco di inizializzazione dei membri. Così è possibile assegnare ad esso nel corpo del costruttore:

A::A { 
    mfs[0] = &A::foo; 
} 

... oppure utilizzare un tipo che può effettivamente essere inizializzato lì come std::vector o boost::array:

struct A { 
    const std::vector<MemFuncPtr> mfs; 
    // ... 
}; 

namespace { 
    std::vector<MemFuncPtr> init_mfs() { 
     std::vector<MemFuncPtr> mfs; 
     mfs.push_back(&A::foo); 
     mfs.push_back(&A::bar); 
     return mfs; 
    } 
} 

A::A() : mfs(init_mfs()) {} 
+0

Si potrebbe anche considerare il buon uso di std :: function. – Puppy

+0

@DeadMG: ho menzionato la versione TR1 ma sono andato alla versione Boost in quanto ha la più ampia disponibilità. Personalmente considero le versioni di C++ 0x come non sufficientemente diffuse e il nuovo standard non è ancora finalizzato. –

+0

Ah, così l'hai fatto. Dal momento che ho ottenuto un compilatore C++ 0x, non sono abituato a vedere le varianti di boost. – Puppy

2

Quello che stai cercando per i punti alle funzioni membro. Ecco un breve esempio che mostra la loro dichiarazione e l'utilizzo:

#include <iostream> 

class B { 
public: 
    B(int foo): foo_(foo) { 
    std::cout << "Making a B with foo_ = " << foo_ << std::endl; 
    } 
    ~B(void) { 
    std::cout << "Deleting a B with foo_ = " << foo_ << std::endl; 
    } 
    int foo_; 
}; 

class A { 
public: 
    A(void) { 
    funcs_[0] = &A::foo; 
    funcs_[1] = &A::bar; 
    } 

    B* foo(void) { 
    return new B(3); 
    } 

    B* bar(void) { 
    return new B(5); 
    } 

    // Typedef for the member function pointer, for everyone's sanity. 
    typedef B* (A::*BMemFun)(void); 
    BMemFun funcs_[2]; 
}; 

int main(int argc, char *argv[]) { 
    A a; 
    for (int i = 0; i < 2; ++i) { 
    A::BMemFun func = a.funcs_[i]; 
    // Call through the member function pointer (the .* operator). 
    B* b = (a.*func)(); 
    delete b; 
    } 
    return 0; 
} 

Il C++ FAQ section on pointers to member functions è dove ho trovato tutte queste informazioni.