Klassenfunktion als Parameter übergeben



  • Hallo,

    ich habe neulich eine Frage bekommen, bei der ich nicht so ohne weiteres eine Antwort gefunden habe.

    Die Beschreibung ist sehr einfach:

    Ich habe eine Klasse, in der zwei Klassen-Funktionen vorhanden sind. Nun möche ich die eine Funktion als Parameter für die andere übergeben.
    Wie stelle ich es an? Eine globale Funktion oder eine statische ist kein Problem, aber die Kassenfunktion kann nicht so einfach übergeben werden. Aber vielleicht hat da jemand eine Lösung.

    Hier ein vereinfachtes Beispiel:

    double foo::GibDieEingabeAus(double Ein)
    {
        return Ein;
    }
    double foo::AddiereEinZurFunktionAnStelleEin(double (*f) (double), double Ein)
    {
        return (*f)(Ein) + Ein;
    }
    
    // irgendwann aufrufen:
    ... // geht alles nicht 
        AddiereEinZurFunktionAnStelleEin(&foo::GibDieEingabeAus, 2);
        AddiereEinZurFunktionAnStelleEin(foo::GibDieEingabeAus, 2);
        AddiereEinZurFunktionAnStelleEin(GibDieEingabeAus, 2);
    ...
    

    Vielleicht etwas noch zum Hintergrund. Ich habe keine Möglichkeit globale Funktionen zu declarieren und ich brauche beide Funktionen nur in der Klasse, von außen muss man nicht drauf zugreifen können.

    Ich bin kein Programmierer, sondern ein Ingenieur, deswegen wäre eine kleine Erklärung zur einer einfachen Lösung das Optimum für mich.

    Danke schön.



  • Hi,

    double foo::GibDieEingabeAus(double Ein) 
    { 
        return Ein; 
    } 
    double foo::AddiereEinZurFunktionAnStelleEin(double (foo::*f) (double), double Ein) 
    { 
        return (this->*f)(Ein) + Ein; 
    } 
    
    // irgendwann aufrufen: 
    ... // geht alles nicht 
        AddiereEinZurFunktionAnStelleEin(&foo::GibDieEingabeAus, 2); 
    ...
    

    Die Syntax ist etwas seltsam. Warum der Aufruf des Methodenzeigers so aussehen muss, kann ja vielleicht jemand anderes erklären. 😉



  • Hallo.

    Danke, es funktioniert tadellos.

    Aber die Erklärung für den -> Operator würde sehr angebracht sein. Ich habe nicht so die Ahnung, was er macht und warum er hier nun vorhanden sein muss.

    Aber jetzt kann ich schon weitermachen, das ist super.



  • Ich rate schon Mal. Wenn man was Falsches sagt, wird man hier oft schnell korrigiert:

    Objektzeiger-> sorgt dafür, dass die nachfolgende Funktion als unsichtbares Argument den Zeiger übergeben bekommt. Das ist ja nötig, da jede Methode quasi nur eine Funktion mit Objektzeiger dazu ist.

    Klar ist, dass Du Deiner Methode die Adresse einer anderen Methode übergeben hast. Aber die kannst Du ja schlecht ohne Objekt aufrufen. Daher musst Du this->*bla schreiben. *bla schreibst Du, weil das ja ein Methodenzeiger und keine Methodenreferenz (was es leider nicht gibt) ist. Die Klammerung ist nötig, weil der Funktionsaufrufoperator() (?) stärker bindet als ::.



  • Fast, Eisflamme. Das mit der Klammerung ist soweit richtig. Allerdings ist ->* ein eigener, einzelner Operator, der sogar für sich überladen werden kann 😉



  • Oh. Und betrifft der nur Methodenzeiger oder hat der auch noch andere Gründe? Wie sieht's mit Zeiger-Attributen aus?



  • Meinst du vielleicht sowas? http://ideone.com/68vcb



  • Hm, nein, aber das ist auch sehr interessant. Ich dachte daran, ob man mit ->* irgendwie auch ein Attribut der Klasse benutzen kann, das ein Zeiger ist. Also quasi bla->*a statt *(bla->a) oder so. Aber das geht wohl nicht.

    Also könnte man ->* als Klassenmemberzeiger-Zugriffsoperator bezeichnen?



  • Korrekt 🙂



  • Suuuuper, wieder was gelernt, dankö.


Anmelden zum Antworten