Übergeben eines Zeigers auf eine Klassenmitgliedsfunktion als Parameter

Lesezeit: 3 Minuten

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

  • 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

Benutzer-Avatar
Felix Glas

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

  • void test::call_cb_func() { (this->*cb_func)(); Man möchte NIEMALS eine Funktion per Zeiger aus dem Objekt heraus aufrufen. Daher ist das „this“ im Beispiel eine völlig nutzlose Erklärung. Angesichts der Tatsache, dass C++ neben hex die möglicherweise unmenschlichste Syntax ist, kann man nicht einfach raten, wie man die Funktion von einem ANDEREN Objekt aus aufruft.

    Benutzer4961492

    1. Juni 2015 um 15:53 ​​Uhr


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

1012210cookie-checkÜbergeben eines Zeigers auf eine Klassenmitgliedsfunktion als Parameter

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy