FunktionsPointer



  • Hallo,
    ich möchte gerne Funktionspointer nutzen, jedoch funktioniert folgender Code nicht:

    #include <iostream>
    
    class MyClass 
    {
    	public:
    		void Func(wchar_t *x1, wchar_t *x2)
    		{
    			std::cout << "Func(*, *)\n";
    		}
    };
    
    typedef void (MyClass::*myFunc)(wchar_t *x1, wchar_t *x2);
    
    struct Data
    { 
    	// Alle für Interface aufrufbare Funktionen:
    	myFunc Func;
    };
    
    class Interface
    {
    	public:
    		virtual void onInit(Data *MyData)
    		{
    			std::cout << "onInit()\n";
    		}
    };
    
    int main()
    {
    	MyClass Test;
    	Data Init;
     	Init.Func = &Test.Func; // error C2276: '&': Ungültige Operation auf Ausdruck einer gebundenen Memberfunktion
            //onInit(Data);
    }
    

    Wie mache ich das richtig? Und wird das so überhaupt in C++ gemacht?

    Vielen Dank,
    IchWeißNichtWeiter



  • Hi,

    es muss so aussehen:

    Init.Func = &MyClass::Func;
    

    Stell es dir so vor. Die Klassen haben Funktion, die es nur einmal im Speicher gibt. Nun willst du ein Funktionspointer auf eine Memberfunktion. Deswegen musst du eine Art "Offset" übergeben, wo sich die Funktion befindet.

    In deinem Fall zeigt Init.Func an diese Speicherstelle, wo MyClass::Func ist.
    Wenn du nun ein Objekt hast, kannst du über den Offset Init.Func zu dessen Funktion gelangen.

    MyClass Test;
    Data Init;
    Init.Func = &MyClass::Func;
    
    (Test.*Init.Func)(L"d",L"fdf");
    


  • Hallo Kasf,
    ich möchte gerne nur einige Funktionen aus meiner Klasse bereitstellen um Msisbrauch zu vermeiden! Gibt es eine Möglichkeit dazu?

    Die Klasse Interface stellt die spätere Klasse dar. Diese Funktion soll di Möglichkeit haben die Funktion Func(,) aufzurufen, aber KEINE andere. Um das sauber zu haben möchte ich aber nicht einfach nur mit private usw... arbeiten.

    Wie denkt ihr darüber?

    Danke

    Viele Grüße,
    IchWeißNichtWeiter



  • IchWeißNichtWeiter schrieb:

    ich möchte gerne nur einige Funktionen aus meiner Klasse bereitstellen um Msisbrauch zu vermeiden!

    Von welcher Art Missbrauch sprichst du ? Ich verstehe nicht ganz den Sinn, aber weiß dennoch was du vorhast 😉

    Ich lass mir was einfallen ...



  • Was hältst du davon:

    class MyClass
    {
        public:
            void func()
            {
                cout << "func()" << endl;
            }
    
            void blub()
            {
                cout << "blub()" << endl;
            }
    
            void sinn()
            {
                cout << "sinn()" << endl;
            }
    
    };
    
    class InterfaceForMyClass : public MyClass {
    
        private:
                using MyClass::func;
    
    };
    
    class Interface
    {
        public:
            virtual void onInit(InterfaceForMyClass& MyData)
            {
                 MyData.func();
            }
    };
    
    int main()
    {
        Interface inter;
        InterfaceForMyClass myinter;
    
        inter.onInit(myinter);
    }
    

    Die Funktion, die nicht für Interface's onInit gedacht sind, werden einfach in InterfaceForMyClass in den privaten Sichtbarkeitsbereich "geswappt".

    Wolltest du sowas haben ?



  • Ja, ich denke so kann ichs machen. Ich muss allerdings, dann von der 1 Klasse in dei andere casten, da ich schon eine Instanz dieser habe. Außerdem müsste ich eine mehrfachvererbung machen, dann wids allerdings kompliziert oder kann man das einfach so machen?

    Also ich habe z.B. 3 Klassen und ich brauche aus jeder dieser Klassen nur 1-2 Funktionne, da die Funktion die diese übergeben bekommt, an den anderen nichts rumzufummeln hat 🙂

    Kann ich das dann noch immer so machen?



  • Also ich habs ausprobiert, so funktionierts nicht wie es soll.

    Also ich habe eine Klasse die schon instanziert wurde. Ich möchte nun Funktionen dieser und noch einer anderen schon instanzieren Klasse abspeichern. Ich mache also z.B. ein struct:

    //Pseudo - Code
    Klasse1
    Klasse1
    
    struct Functions
    {
     Klasse1::Func1...
     Klasse2::Func2...
    };
    
    onInit(Func)
    {
     Func.Func1
     Func.Func2
    }
    

    Dieses struct übergebe ich dann an die Funktion onInit und es kann dann exakt diese Funktionen aufrufen und NUR diese. Ist das machbar? Ich weiß leider nicht wie ichs machen soll 😞

    Vielen Dank,
    IchWeißNichtWeiter



  • Ja klar ist das machbar, falls ich dich richtig verstanden habe. Du kannst es doch so wie in deinem ersten Code machen.

    Also dir eine Struktur mit Funktionspointer anlegen, die im Konstruktor der Struktur mit dem zugehörigen Funktion initalisiert werden.

    Deiner oninit-Funktion übergibst du diese Struktur und ein zughöriges Objekt und rufst dann die Funktion auf.

    Aber das macht nicht viel Sinn, da man immer noch die Möglichkeit hätte in oninit() über das Objekt normal alle Funktion aufzurufen.

    Dann lieber in dein struct noch ein MyClass Objekt als private reinpacken und nur public Wrapper Funktion bereitstellen, die auf bestimmte Funktion von MyClass zugreifen ...



  • Kannst du dazu noch kurz ein Beispiel machen? Ich komme nicht ganz mit 😞

    Danke 🙂 👍



  • Das wäre IMHO die beste Lösung dafür:

    struct MyClassWrapper {
    
        private:
                MyClass myclass;
    
        public:
                void blub()
                {
                    myclass.blub();
                }
    
                void sinn()
                {
                    myclass.sinn();
                }
    };
    
    class Interface
    {
        public:
            virtual void onInit(MyClassWrapper& obj)
            {
                obj.blub();
            }
    };
    

    Also MyClass wrappen und nur bestimmte Funktion zur Verfügung zu stellen.

    Bei der Geschichte mit den Funktionspointer braucht man ja auch immer ein Objekt dazu und mit dem könnte man auch immer die Funktionen ohne die Funktionspointer aufrufen.



  • ... oder mit Referenz (je nachdem, was man will):

    KasF schrieb:

    struct MyClassWrapper {
    
        private:
                MyClass& myclass;
    ...
    

    Eigentlich könnte man sich noch Gedanken über const-correctness machen (reicht eine const& ? sind blubb() und sinn() const ? ...)

    Gruß,

    Simon2.



  • Vielen Dank! Das hat mir SEHR weitergeholfen 🙂

    Viele Grüße,
    IchWeißNichtWeiter


Anmelden zum Antworten