alternative Lösung zu callbacks einer Member Funktion?



  • Hallo,
    ich versuche mein Problem zu schreiben.

    Folgende Klassen haben ich:

    - Klasse A erbt von Klasse B
    - Klasse B hat eine vector Variable von Klasse C
    - Klasse C hat als Variablen einen seiten index und eine callback funktion

    -> die idee ich definiere in klasse a Seiten mit index und übergebe member funktionen als callbacks,
    beim aufrufen der seite mithilfe des index wird automatisch die entsprechende funktion (callback, member function von a) aufgerufen.

    leider kann ich die member funktion von klasse a nicht in klasse c "speichern" zuweisen, kommt eine schöne static fehlermeldung.

    habt ihr eine idee wie so etwas alternativ gelöst werden kann?

    #include <vector>
    #include <iostream>
    
    using namespace std;
    
    typedef void (*callback)();
    
    class page{
    	public:
    		page(int index, callback func);
    		void update_page(void);
    		int get_index(void){return index;};
    	private:
    		int index;
    		callback function;
    };
    
    class the_sub{
    	public:
    		the_sub();
    		void the_page(void);
    		void add_page(int index, callback func);
    		void update(int index);
    	private:
    		std::vector<page> pages;
    };
    
    class the_main : the_sub{
    	public:
    		the_main();
    		void print_something(void);
    		void display_the_class_text(void);
    		void add_the_page(int index);
    		void the_update_func(void);
    		void update(int index){the_sub::update(index);};
    	private:
    
    };
    
    void xyz(void)
    {
    	cout << "display the text" << endl;
    }
    
    page::page(int index, callback func)
    {
    	this->index = index;
    	this->function = func;
    
    }
    
    void page::update_page(void)
    {
    	this->function();
    }
    
    the_sub::the_sub()
    {
    
    }
    
    void the_sub::add_page(int index, callback func)
    {
    	page tmp(index, func);
    	pages.push_back(tmp);
    }
    
    void the_sub::update(int index)
    {
    	for(unsigned int i=0; i < pages.size(); i++)
    	{
    		if(pages.at(i).get_index() == i)
    			pages.at(i).update_page();
    	}
    
    }
    
    the_main::the_main(void)
    {
    
    }
    void the_main::add_the_page(int index)
    {
    	//callback t = (callback)&(this->display_the_class_text);
    	add_page(index, (callback)&(this->display_the_class_text));
    }
    
    void the_main::print_something(void)
    {
    	cout << "something more " << endl;
    }
    
    void the_main::display_the_class_text(void)
    {
    	cout << "display the_main::text!" << endl;
    	print_something();
    }
    
    int main(void)
    {
    
    	the_main tm;
    	//callback t = (callback)&tm.display_the_class_text;
    	tm.add_the_page(0);
    	tm.update(0);
    
    	cout << "main" << endl;
    
    	return 0;
    }
    

    ich hoffe ihr versteht mein anliegen halbwegs.

    vielen dank!



  • Stichwort: Memberfunktionszeiger ("member function pointer")

    Am besten, du benutzt einfach std::function:

    #include <functional>
    
    class the_sub;
    
    typedef std::function<void(the_sub&)> callback;
    


  • Th69 schrieb:

    Stichwort: Memberfunktionszeiger ("member function pointer")

    Am besten, du benutzt einfach std::function:

    #include <functional>
    
    class the_sub;
    
    typedef std::function<void(the_sub&)> callback;
    

    Hallo,
    vielen Dank für das Beispiel.

    Könntest du mir etwas weiter auf die Sprünge helfen,
    den Source Code entsprechend anpassen?

    Danke



  • ich habe es probiert, allerdings keine änderung 😡
    ist ein gcc für arm der compiler

    #include <vector>
    #include <iostream>
    #include <functional>
    
    using namespace std;
    
    class the_sub;
    class the_main;
    typedef std::function<void(the_main&)> callback;
    
    class page{
        public:
            page(int index, callback func);
            void update_page(void);
            int get_index(void){return index;};
        private:
            int index;
            callback function;
    };
    
    class the_sub{
        public:
            the_sub();
            void the_page(void);
            void add_page(int index, callback func);
            void update(int index);
        private:
            std::vector<page> pages;
    };
    
    class the_main : the_sub{
        public:
            the_main();
            void print_something(void);
            void display_the_class_text(void);
            void add_the_page(int index);
            void the_update_func(void);
            void update(int index){the_sub::update(index);};
        private:
    
    };
    
    void xyz(void)
    {
        cout << "display the text" << endl;
    }
    
    page::page(int index, callback func)
    {
        this->index = index;
        this->function = func;
    
    }
    
    void page::update_page(void)
    {
        //this->function();
    }
    
    the_sub::the_sub()
    {
    
    }
    
    void the_sub::add_page(int index, callback func)
    {
        page tmp(index, func);
        pages.push_back(tmp);
    }
    
    void the_sub::update(int index)
    {
        for(int i=0; i < (int)pages.size(); i++)
        {
            if(pages.at(i).get_index() == i)
                pages.at(i).update_page();
        }
    
    }
    
    the_main::the_main(void)
    {
    
    }
    void the_main::add_the_page(int index)
    {
        callback t = this->display_the_class_text;
        add_page(index, t);
    }
    
    void the_main::print_something(void)
    {
        cout << "something more " << endl;
    }
    
    void the_main::display_the_class_text(void)
    {
        cout << "display the_main::text!" << endl;
        print_something();
    }
    
    int main(void)
    {
    
        the_main tm;
        //callback t = (callback)&tm.display_the_class_text;
        tm.add_the_page(0);
        tm.update(0);
    
        cout << "main" << endl;
    
        return 0;
    }
    


  • Es wäre schon hilfreich gewesen, wenn du den Fehler auch genannt hättest...

    Problem ist hier:

    callback t = this->display_the_class_text;
    

    Du hast dein Callback doch als Funktion mit Parameter the_main& -> void deklariert. Das Problem ist hier, dass
    a) display_the_class_text nicht diesen Parameter hat
    b) display_the_class_text ist eine Member-Funktion!

    b) ist besonders wichtig, weil man Member-Funktionen nur mit zugehörigem Objekt aufrufen kann.

    Das heißt, du könntest mit bind den Wert this als ersten Parameter an die entsprechende mem_fn binden.

    Oder besser/einfacher: nimm ein Lambda, das den this-Pointer captured und den Parameter the_main& verwirft:

    callback t = [this](the_main&){ this->display_the_class_text(); };
    

    Damit sollte es kompilieren. Habe jetzt nicht genau geschaut, ob da sonstwo noch andere Probleme drin sind.

    PS: Ich habe den Originalpost nicht ganz gelesen - wozu ist der Parameter überhaupt gut?



  • hallo,
    danke für den tipp
    bind und function waren die mir fehlenden schlüsselwörter

    class the_sub;
    class the_main;
    typedef std::function<void(the_main&)> callback;
    
    class page{
        public:
            page(int index, std::function<void()> func);
            void update_page(void);
            int get_index(void){return index;};
        private:
            int index;
            std::function<void()> function;
    };
    
    class the_sub{
        public:
            the_sub();
            void the_page(void);
            void add_page(int index, std::function<void()> func);
            void update(int index);
        private:
            std::vector<page> pages;
    };
    
    class the_main : the_sub{
        public:
            the_main();
            void print_something(void);
            void display_the_class_text(void);
            void add_the_page(int index);
            void the_update_func(void);
            void update(int index){the_sub::update(index);};
        private:
    
    };
    
    void xyz(void)
    {
        cout << "display the text" << endl;
    }
    
    page::page(int index, std::function<void()> func)
    {
        this->index = index;
        this->function = func;
    
    }
    
    void page::update_page(void)
    {
        this->function();
    }
    
    the_sub::the_sub()
    {
    
    }
    
    void the_sub::add_page(int index, std::function<void()> func)
    {
        page tmp(index, func);
        pages.push_back(tmp);
    }
    
    void the_sub::update(int index)
    {
        for(int i=0; i < (int)pages.size(); i++)
        {
            if(pages.at(i).get_index() == i)
                pages.at(i).update_page();
        }
    
    }
    
    the_main::the_main(void)
    {
    
    }
    void the_main::add_the_page(int index)
    {
    	//std::function<void(void)> t = std::bind(&the_main::display_the_class_text, this);
        add_page(index, std::bind(&the_main::display_the_class_text, this));
    }
    
    void the_main::print_something(void)
    {
        cout << "something more " << endl;
    }
    
    void the_main::display_the_class_text(void)
    {
        cout << "display the_main::text!" << endl;
        print_something();
    }
    
    int main(void)
    {
    
        the_main tm;
        //callback t = (callback)&tm.display_the_class_text;
        tm.add_the_page(0);
        tm.update(0);
    
        cout << "main" << endl;
    
        return 0;
    }
    

Log in to reply