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
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()) {}
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.
Si potrebbe anche considerare il buon uso di std :: function. – Puppy
@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. –
Ah, così l'hai fatto. Dal momento che ho ottenuto un compilatore C++ 0x, non sono abituato a vedere le varianti di boost. – Puppy