Funktionszeiger: Array



  • Hallo,

    Ich versuche in dem dargestellten Beispiel, eine Class mit einem Array von Funktionszeigern zu anderen Classes zu erstellen.
    Beschwert sich der Compiler über den Ausdruck in Line 22 der 'test1.cpp'.

    Habe ich an irgendeiner Stelle das Array falsch definiert?

    Danke im Voraus!

    // test1.h
    #include <iostream>
    
    class Caller;   
    typedef void (Caller::*functpointer)();
    
    class Caller {
    public:
    	Caller(); 
    	~Caller();  
        functpointer array1[];
    	};
    
    class Functions {
    	void a();
    	void b(); 
    public:
        Functions::Functions();
        Functions::~Functions();	
    	friend class Caller;
    	};
    
    // test1.cpp
    #include "test1.h"
    
    using namespace std;
    
    Functions::Functions() {};
    
    Functions::~Functions() {};
    
    void Functions::a(){
    	cout << "a is called" << endl;
    	}
    
    void Functions::b(){
    	cout << "b is called" << endl;	
    	}
    
    Caller::Caller(){
        array1[] = { &Functions::a , &Functions::b };
    	};
    
    Caller::~Caller() {};
    
    // main.cpp
    #include "test1.h"
    
    using namespace std;
    
    int main(){
    	Caller class1;
    }
    


  • Die Syntax ist falsch. Du kannst das Array so nicht initialisieren, sondern musst jedes Element explizit zuweisen. Außerdem muss die Größe des Arrays bekannt sein.

    // deklaration des arrays
    class Caller
    {
        functpointer array1[2];
    };
    
    // konstruktor
    Caller::Caller()
    {
        array1[0] = &Functions::a;
        array1[1] = &Functions::b;
    };
    

    Mit einer kleinen Änderung geht es eleganter:

    // deklaration
    class Caller
    {
        static functpointer array1[2];
    };
    
    // implementierung
    functpointer Caller::array1[2] =
    { 
        &Functions::a, 
        &Functions::b
    };
    

    Ist dann aber für alle Caller-Instanzen das gleiche Array!
    Und das funktioniert in jedem Fall sowieso nur, wenn und a und b statische Memberfunktionen sind, sonst fliegt es dir wieder um die Ohren, weil die Aufrufkonventionen nicht passen.



  • Vielen Dank für Deine Antwort!

    Sobald ich Deine beschriebenen Änderungen übernehme, beschwert sich der Compiler erneut über die Zeilen 10 und 11.
    "cannot convert ‘void (Functions::)()’ to ‘void (Caller::)()’ in assignment".

    // deklaration des arrays
    class Caller
    {
        functpointer array1[2];
    };
    
    // konstruktor
    Caller::Caller()
    {
        array1[0] = &Functions::a;
        array1[1] = &Functions::b;
    };
    

    Ich verstehe nicht ganz, warum es Probleme mit dem Scope der Funktionen gibt.



  • Das ist nicht wirklich ein Problem des Scopes. Das Array das du deklarierst, ist ein Array, das Zeiger auf Memberfunktionen der Klasse Caller, die keine Parameter nehmen und void zurückgeben, enthält.

    Du kannst naheliegenderweise dann NICHT Zeiger auf Memberfunktionen einer ANDEREN Klasse in das Array stecken.

    Felix

    EDIT: Und natürlich musst du die Größe des Arrays schon bei der Deklaration angeben!
    EDIT2: Achso, hast du ja schon geändert.

    Wenn du die Änderung von meinem Nachposter machen willst, musst du natürlich die andere Klasse forward-deklarieren.



  • Ah, ich hab vorhin deine Deklaration der Funktionspointer überlesen. Dein Array will Caller -Funktionen, du gibst ihm aber Functions -Funktionen. Du solltest also

    typedef void (Caller::*functpointer)();
    

    nach

    typedef void (Functions::*functpointer)();
    

    ändern.



  • Vielen Dank!

    Ich habe die den Scope des Typedef geändert und schreibe nun:

    typedef void (Functions::*functpointer)();
    

    Der Scope Functions bezieht sich also auf die Funktionen, die referenziert werden und nicht auf den Scope in dem sich die Pointer selbst befinden.

    Macht auch irgendwie Sinn 🙂



  • Vielen Dank!

    Ich habe die den Scope des Typedef geändert und schreibe nun:

    typedef void (Functions::*functpointer)();
    

    Der Scope Functions bezieht sich also auf die Funktionen, die dadurch referenziert werden und nicht auf den Scope, in dem sich die Pointer selbst befinden.

    Macht auch irgendwie Sinn 🙂


Log in to reply