Nie ma nic złego w używaniu wskaźników funkcji. Jednak wskaźniki do niestatycznych funkcji składowych nie są podobne do zwykłych wskaźników do funkcji: funkcje składowe muszą być wywoływane w obiekcie, który jest przekazywany jako niejawny argument funkcji. Zatem podpis twojej funkcji członkowskiej powyżej to
void (aClass::*)(int, int)
zamiast typu, którego próbujesz użyć
void (*)(int, int)
Jedno podejście mogłoby polegać na utworzeniu funkcji składowej, static
w którym to przypadku nie wymaga ona wywołania żadnego obiektu i można jej użyć z typem void (*)(int, int)
.
Jeśli potrzebujesz dostępu do dowolnego niestatycznego elementu członkowskiego swojej klasy i musisz trzymać się wskaźników do funkcji, np. Ponieważ funkcja jest częścią interfejsu C, najlepszą opcją jest zawsze przekazywanie void*
do funkcji a, przyjmując wskaźniki do funkcji i wywołując Twój element członkowski za pośrednictwem funkcji przekazującej, która uzyskuje obiekt z, void*
a następnie wywołuje funkcję składową.
W odpowiednim interfejsie C ++ możesz rzucić okiem na to, aby Twoja funkcja pobierała argument oparty na szablonie dla obiektów funkcji, aby używały dowolnych typów klas. Jeśli używanie szablonu interfejsu jest niepożądane, powinieneś użyć czegoś takiego std::function<void(int, int)>
: możesz utworzyć dla nich odpowiednio wywoływalny obiekt funkcji, np std::bind()
. Using .
Podejścia z bezpiecznym typem przy użyciu argumentu szablonu dla typu klasy lub odpowiedniego std::function<...>
są lepsze niż użycie void*
interfejsu, ponieważ eliminują potencjalne błędy wynikające z rzutowania na niewłaściwy typ.
Aby wyjaśnić, jak używać wskaźnika funkcji do wywoływania funkcji składowej, oto przykład:
// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
fptr(context, 17, 42);
}
void non_member(void*, int i0, int i1) {
std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}
struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
}
};
void forwarder(void* context, int i0, int i1) {
static_cast<foo*>(context)->member(i0, i1);
}
int main() {
somefunction(&non_member, 0);
foo object;
somefunction(&forwarder, &object);
}