Funktionszeiger



  • Hallo zusammen.
    Ursprünglich wollte ich einen Funktionszeiger als Member-Variable in einer Klasse haben. In der gleichen Klasse sollte eine Funktion sein, die sich auf diesen Zeiger beruft. Der Funktionszeiger sollte auf eine Funktion ausserhalb dieser Klasse zeigen.

    Nachdem das nicht funktionierte, startete ich folgenden, kleines Test-Prg. das eine Member-Funktion und einen Funktionszeiger hat und im Konstruktor soll der Zeiger auf die Funktion gebogen werden :

    // Header :
    
    class test  
    {
    public:
        test();
        virtual ~test();
        void (*pFunc) (int); // Funktionszeiger
        void dummy(int);     // Testfunktion
    };
    
    //----------------------------------------------------------------
    
    test::test()
    {
        pFunc=dummy;    // Hier hängts, aber warum?
    }
    
    test::~test()
    {
    }
    
    void test::dummy(int a)
    {
        a++;
    }
    

    Der Compiler antwortet mir :
    error C2440: '=' : 'void (__thiscall test::*)(int)' kann nicht in 'void (__cdecl *)(int)' konvertiert werden
    Es gibt keinen Kontext, in dem diese Konvertierung moeglich ist.

    Warum klappt das nicht ?
    Kann ich Funktionszeiger in Klassen überhaupt verwenden ?

    MFG,
    elysis



  • Kann ich Funktionszeiger in Klassen überhaupt verwenden ?

    nein, nur wenn diese static sind



  • Original erstellt von elysis:
    **Hallo zusammen.
    Ursprünglich wollte ich einen Funktionszeiger als Member-Variable in einer Klasse haben. In der gleichen Klasse sollte eine Funktion sein, die sich auf diesen Zeiger beruft. Der Funktionszeiger sollte auf eine Funktion ausserhalb dieser Klasse zeigen.

    Nachdem das nicht funktionierte,**

    Das hätte aber funktionieren sollen:

    class Foo {
      void (*fptr)();
     public:
      Foo(void (*p)()): fptr(p) { }
      void call() {
        fptr();
      }
      // ...
    };
    ...
    void bar() { ... }
    ...
    Foo foo(bar);
    foo.call();
    


  • An der Stelle :

    Foo foo(bar);
    

    erhalte ich die Fehlermeldung :

    error C2664: '__thiscall Foo::Foo(void (__cdecl *)(void))' : Konvertierung des Parameters 1 von 'void (void)' in 'void (__cdecl *)(void)' nicht moeglich
    Keine Funktion mit diesem Namen im Gueltigkeitsbereich stimmt mit dem Zieltyp ueberein.

    Schade.



  • der Fehler ist mir nicht nachvollziehbar, g++ 3.2.2 und 2.95.4 compilieren es ohne Probleme.

    Was soll void(void) eigentlich fürn Typ sein?



  • Original erstellt von elysis:
    **```cpp
    ...
    test::test()
    {
    pFunc=dummy; // Hier hängts, aber warum?
    }

    Weil dummy(int) doch noch den versteckten this-Zeiger hat, und das kann man,
    wie kingruedi schon sagte mit einer static Funktion vermeiden.



  • Was soll void(void) eigentlich fürn Typ sein?

    <Ratemodus>
    Wahrscheinlich der gleiche wie void (). Und damit "Funktion die nix liefert und keine Argumente erwartet"
    </Ratemodus>



  • //Es gab bereits einen Thread mit Lösung dazu. Hier ein Beispielprogramm:

    extern "C"
    {
    #include <stdio.h>
    }

    class A
    {
    public:

    A(){ g=&A::f;}

    int f() { printf( "f
    ");}

    int ( A::*g)( void);
    };

    int main ()
    {
    A foo;

    ( foo.*foo.g)();
    }

    // Hier der Thread: C++ Memberfunktionspointer ausserhalb einer Klasse aufrufen



  • Original erstellt von HumeSikkins:
    **Wahrscheinlich der gleiche wie void (). Und damit "Funktion die nix liefert und keine Argumente erwartet"
    **

    dann ist also void bar() aus irgendeinem Grund nicht __cdecl. Aber warum nicht, und was anstatt dessen? Und wieso gehts bei mir?

    Das ist mein Testcode:

    class Foo {
        void (*fptr)();
     public:
        Foo(void (*p)()): fptr(p) { }
        void call() {
            fptr();
        }
       // ...
    };
    
    void bar() { return; }
    int main() {
        Foo foo(bar);
        foo.call();
    }
    


  • Original erstellt von elysis:
    **An der Stelle :
    error C2664: '__thiscall Foo::Foo(void (__cdecl *)(void))' : Konvertierung des Parameters 1 von 'void (void)' in 'void (__cdecl *)(void)' nicht moeglich
    Keine Funktion mit diesem Namen im Gueltigkeitsbereich stimmt mit dem Zieltyp ueberein.
    **

    *ratten teil 2*
    vielleicht will der compiler ein & davor, um einen zeiger draus zu machen (aus void(void) wird void(*)(void))
    /ratten teil 2

    ein schöner fehler, den mein compiler zum glück nicht hat 🙂



  • @Bashar
    Scheinbar redet ihr aneinander vorbei. Der von dir gepostete Code funktioniert auch unter dem VC anstandslos (das Format der geposteten Fehlermeldung lässt mich vermuten, dass der OP ebenfalls den VC einsetzt).


Anmelden zum Antworten