Funktionsname an anderes Objekt übergeben und ausführen



  • Ich hatte das Beispiel hier gesehen
    http://www.radmangames.com/programming/how-to-use-boost-bind

    #include "boost/function.hpp" 
    #include "boost/bind.hpp" 
    
    #include <string> 
    #include <iostream> 
    
    namespace 
    { 
      void function(int number, float floatation, std::string string) 
      { 
        std::cout << "Int: \"" << number << "\" Float: \"" << floatation 
                  << "\" String: \"" << string << "\"" << std::endl; 
      } 
    
    } // namespace 
    
    int main(int c, char** argv) 
    { 
      // declare function pointer variables 
      boost::function<void(std::string, float, int)> shuffleFunction; 
      boost::function<void(void)> voidFunction; 
      boost::function<void(float)> reducedFunction; 
    
      // bind the methods 
      shuffleFunction = boost::bind(::function, _3, _2, _1); 
      voidFunction = boost::bind(::function, 5, 5.f, "five"); 
      reducedFunction = boost::bind(::function, 13, _1, "empty"); 
    
      // call the bound functions 
      shuffleFunction("String", 0.f, 0); 
      voidFunction(); 
      reducedFunction(13.f); 
    
    } // main
    

    wenn ::function wenigstens ein String sein könnte wäre das alles kein Problem.



  • @Bennisen
    Naja C++ kann das einfach nicht.
    Wenn du uns verrätst was das X zu deinem Y ist können wir dir aber vielleicht trotzdem helfen.

    Oder anders gesagt...

    Bennisen schrieb:

    aber leider kann ich das nicht auf meine Situation anwenden.

    Und zwar wieso nicht?



  • Bei mir hakt es an der Übergabe von Objekt1 zu Objekt2, da weiß ich nicht genau wie ich das machen soll. Zu mal die Beispiele die ich gesehen habe, es benötigen das die Funktion, die ich übergeben will, in Objekt1 existieren muss.Bei diesem Beispiel

    // member 
      Class* objPtr = new Class(); 
      typedef void (Class::*OverloadFuncType)(float); 
      boost::bind(static_cast<OverloadFuncType>(&Class::overload), objPtr, _1);
    

    ist mir nicht ganz klar wo die Funktion selber landet. Kann ich sie irgendwo drin speichern?
    Wenn ich die Funktion selber irgendwie in Objekt2 bekommen würde, dann käme ich schon ein ganzes Stück weiter.


  • Mod

    Erklär doch einfach, was du letztlich erreichen möchtest, anstatt zu versuchen (völlig veralteten) Code zu entziffern, der höchstwahrscheinlich überhaupt nichts mit einer späteren Lösung zu tun haben wird.



  • Ich habe eine Klasse die sich Params nennt. Diese nimmt die Argumente entgegen die von der Commandline kommen. Diese sollen dann in der Params Klasse überprüft werden und die entsprechende Funktion soll an meine andere Klasse System übergeben werden. Es wird überprüft wie das Argument argv[1] aussieht. Zum Beispiel "-d" und anhand des Arguments soll eine entsprechende Funktion ausgelöst werden. Ich möchte die Funktion aber nicht direkt aufrufen sondern erst ganz zum Schluss über die Klasse System und der Methode execute.


  • Mod

    Was ist denn die Rolle der System-Klasse in deiner Modellierung und woher kommen überhaupt die Funktionen?



  • Bennisen schrieb:

    Ich habe eine Klasse die sich Params nennt. Diese nimmt die Argumente entgegen die von der Commandline kommen. Diese sollen dann in der Params Klasse überprüft werden und die entsprechende Funktion soll an meine andere Klasse System übergeben werden. Es wird überprüft wie das Argument argv[1] aussieht. Zum Beispiel "-d" und anhand des Arguments soll eine entsprechende Funktion ausgelöst werden. Ich möchte die Funktion aber nicht direkt aufrufen sondern erst ganz zum Schluss über die Klasse System und der Methode execute.

    Suchst du also sowas?

    #include <iostream>
    #include <functional>
    #include <cstring>
    
    class Foo
    {
    public:
    	void setFunction(const std::function<void()>& f)
    	{
    		m_func = f;
    	}
    
    	void execute()
    	{
    		if(m_func)
    			m_func();
    	}
    
    private:
    	std::function<void()> m_func;
    };
    
    void a()
    {
    	std::cout << "a executed" << std::endl;
    }
    
    void b()
    {
    	std::cout << "b executed" << std::endl;
    }
    
    int main(int argc, char** argv)
    {
    	if(argc == 2)
    	{
    		Foo f;
    		if(strcmp(argv[1], "-a") == 0)
    			f.setFunction(a);
    		else if(strcmp(argv[1], "-b") == 0)
    			f.setFunction(b);
    
    		std::cout << "Starting execution" << std::endl;
    		f.execute();
    	}
    }
    

    In einem std::function Objekt kannst du so ziemlich alles speichern was man irgendwie aufrufen kann.



  • @Bennisen
    Kennst du Lambda-Expressions?



  • @seb707 ja sowas ähnliches suche ich, aber momentan glaube ich dass das was ich vorhabe nicht geht. In meinem Fall ist die Funktion a und b in der Klasse Foo. Der Aufruf f.setFunction(a) oder f.setFunction(b) würde dann nicht gehen, da er die Funktion a und b nicht findet.

    @hustbaer schau ich mir mal an



  • Bennisen schrieb:

    @seb707 ja sowas ähnliches suche ich, aber momentan glaube ich dass das was ich vorhabe nicht geht. In meinem Fall ist die Funktion a und b in der Klasse Foo. Der Aufruf f.setFunction(a) oder f.setFunction(b) würde dann nicht gehen, da er die Funktion a und b nicht findet.

    Doch das geht. Gibt mehrere Möglichkeiten, eine davon sind die genannten Lambda Expressions. Würde dann so aussehen:

    Foo f;
    if(strcmp(argv[1], "-a") == 0)
    	f.setFunction([&f]() { f.a(); });
    else if(strcmp(argv[1], "-b") == 0)
    	f.setFunction([&f]() { f.b(); });
    

    Man kann auch irgendwas mit bind oder so ähnlich machen aber seitdem es Lambdas gibt ist das eigentlich obsolet.



  • Nochmal ein vollständigeres Beispiel mit Parametern, Rückgabewerten und beiden Varianten mit Lambdas und std::bind :

    #include <iostream>
    #include <functional>
    #include <cstring>
    
    class Foo
    {
    public:
    	void setFunction(const std::function<int(int)>& f)
    	{
    		m_func = f;
    	}
    
    	void execute(int x)
    	{
    		if(m_func)
    			std::cout << "Function returned: " << m_func(x) << std::endl;
    	}
    
    	int a(int x)
    	{
    		std::cout << "a executed: " << x << std::endl;
    		return 1;
    	}
    
    	int b(int x)
    	{
    		std::cout << "b executed: " << x << std::endl;
    		return 2;
    	}
    
    private:
    	std::function<int(int)> m_func;
    };
    
    int main(int argc, char** argv)
    {
    	if(argc == 2)
    	{
    		Foo f;
    		if(strcmp(argv[1], "-a") == 0)
    			f.setFunction([&f](int x) { return f.a(x); });                 // Lambda
    		else if(strcmp(argv[1], "-b") == 0)
    			f.setFunction(std::bind(&Foo::b, &f, std::placeholders::_1));  // std::bind
    
    		std::cout << "Starting execution" << std::endl;
    		f.execute(7);
    	}
    }
    


  • @sebi707 Vielen Dank dein Beispiel hat mir sehr geholfen.



  • Das [&f](int x) { return f.a(x); } Ding ist im übrigen ne Lambda-Expression 😉


Anmelden zum Antworten