Ich habe ein kleines Programm geschrieben, in dem ich versuche, einen Zeiger auf eine Member-Funktion einer Klasse an eine andere Funktion zu übergeben. Können Sie mir bitte helfen und wo ich falsch liege..?
#include<iostream>
using namespace std;
class test{
public:
typedef void (*callback_func_ptr)();
callback_func_ptr cb_func;
void get_pc();
void set_cb_ptr(void * ptr);
void call_cb_func();
};
void test::get_pc(){
cout << "PC" << endl;
}
void test::set_cb_ptr( void *ptr){
cb_func = (test::callback_func_ptr)ptr;
}
void test::call_cb_func(){
cb_func();
}
int main(){
test t1;
t1.set_cb_ptr((void *)(&t1.get_pc));
return 0;
}
Ich erhalte die folgende Fehlermeldung, wenn ich versuche, es zu kompilieren.
error C2276: '&' : illegal operation on bound member function expression
Sie können einen Funktionszeiger nicht umwandeln void*
.
Wenn Sie möchten, dass ein Funktionszeiger auf a zeigt Mitgliedsfunktion Sie müssen den Typ als deklarieren
ReturnType (ClassType::*)(ParameterTypes...)
Außerdem können Sie keinen Funktionszeiger auf eine gebundene Elementfunktion deklarieren, z
func_ptr p = &t1.get_pc // Error
Stattdessen müssen Sie die Adresse wie folgt erhalten:
func_ptr p = &test::get_pc // Ok, using class scope.
Wenn Sie schließlich einen Funktionszeiger aufrufen, der auf eine Mitgliedsfunktion zeigt, müssen Sie ihn mit einer Instanz der Klasse aufrufen, der die Funktion angehört. Zum Beispiel:
(this->*cb_func)(); // Call function via pointer to current instance.
Hier ist das vollständige Beispiel mit allen angewendeten Änderungen:
#include <iostream>
class test {
public:
typedef void (test::*callback_func_ptr)();
callback_func_ptr cb_func;
void get_pc();
void set_cb_ptr(callback_func_ptr ptr);
void call_cb_func();
};
void test::get_pc() {
std::cout << "PC" << std::endl;
}
void test::set_cb_ptr(callback_func_ptr ptr) {
cb_func = ptr;
}
void test::call_cb_func() {
(this->*cb_func)();
}
int main() {
test t1;
t1.set_cb_ptr(&test::get_pc);
t1.call_cb_func();
}
Zusätzlich zur Antwort von Snps könnten Sie auch a verwenden Funktions-Wrapper von C++11 zum Speichern einer Lambda-Funktion:
#include <iostream>
#include <functional>
class test
{
public:
std::function<void ()> Func;
void get_pc();
void call_cb_func();
void set_func(std::function<void ()> func);
};
void test::get_pc()
{
std::cout << "PC" << std::endl;
}
void test::call_cb_func()
{
Func();
}
void test::set_func(std::function<void ()> func)
{
Func = func;
}
int main() {
test t1;
t1.set_func([&](){ t1.get_pc(); });
t1.call_cb_func();
}
finde ich immer newty.de/fpt/index.html sehr hilfreich.
– Arne
9. August 2013 um 11:43 Uhr
Elementfunktionen sind keine Funktionen. Der Typ, den Sie benötigen, ist
void (test::*)(void *)
…– Kerrek SB
9. August 2013 um 11:43 Uhr
Kerrek SB hat recht. Wenn Sie jedoch beabsichtigen, denselben Member für verschiedene Klassen und Instanzen aufzurufen, sollten Sie an Vererbung und Virtuals denken …
– Manuel del Castillo
9. August 2013 um 12:04 Uhr