2013-08-09 3 views
13

Ich habe ein kleines Programm geschrieben, wo ich versuche, einen Zeiger auf Elementfunktion einer Klasse an eine andere Funktion zu übergeben. Kannst du mir bitte helfen und wo ich falsch liege ..?Übergabe eines Zeigers an eine Klassenmemberfunktion als Parameter

Ich bekomme den folgenden Fehler, wenn ich versuche, es zu kompilieren.

error C2276: '&' : illegal operation on bound member function expression 
+0

Ich finde immer http://www.newty.de/fpt/index.html sehr nützlich. – arne

+2

Mitgliedsfunktionen sind keine Funktionen. Der Typ, den Sie brauchen, ist 'void (test :: *) (void *)' ... –

+1

Kerrek SB hat Recht. Wenn Sie jedoch dasselbe Element für verschiedene Klassen und Instanzen aufrufen möchten, sollten Sie an Vererbung und virtuelle Elemente denken ... –

Antwort

19

Sie können einen Funktionszeiger auf void* gegossen.

Wenn Sie einen Funktionszeiger auf eine Memberfunktion Punkt Sie die Art erklären müssen

ReturnType (ClassType::*)(ParameterTypes...) 

Weiterhin können Sie nicht einen Funktionszeiger auf eine gebundene Elementfunktion deklarieren, z.B.

func_ptr p = &t1.get_pc // Error 

Stattdessen müssen Sie die Adresse wie diese:

func_ptr p = &test::get_pc // Ok, using class scope. 

Schließlich, wenn Sie einen Anruf an einen Funktionszeiger machen auf eine Elementfunktion zeigt, müssen Sie es mit einer Instanz der Klasse aufrufen dass die Funktion ein Mitglied von ist. Zum Beispiel:

(this->*cb_func)(); // Call function via pointer to current instance. 

Hier ist das vollständige Beispiel mit allen Änderungen angewandt:

#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(); 
} 
+1

void test :: call_cb_func() {(dies -> * cb_func)(); Man möchte niemals eine Funktion per Zeiger aus dem Objekt heraus aufrufen. Daher ist das "Dies" im Beispiel eine völlig nutzlose Erklärung. Da C++ neben hex die möglicherweise unmenschlichste Syntax ist, kann man nicht einfach raten, wie man die Funktion von ANDEREM Objekt aufruft. –

2

Neben Snps Antwort, können Sie auch ein function wrapper von C++ 11 verwenden, um eine Lambda zu speichern 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(); 
}