Funktion in struct??



  • Ok, danke. Ich habe das jetzt hier:

    struct TrgSin
    {
      double fx  (double k) {return sin(k);};
      double fx1 (double k) {return cos(k);};
      double fx2 (double k) {return -sin(k);};
      double fx3 (double k) {return -cos(k);};
    } Sin;
    

    Ich möchte nun, dass ich in einer Schleife diese Methoden benutze und zwar immer abwechsle. Wie könnte ich das realisieren. Wenn fx genutzt wurde, dann nutze fx1, dann fx2, dann fx3 und schließlich wieder fx. Ich habe leider keine Idee, wie man das machen könnte. Habt ihr Anregungen?

    vielen Dank
    lg, freakC++



  • Das geht mit z.B Funktionszeiger. Mach draus Funktionszeiger und pack die in ein Array. Dann kannst du da drüber iterieren.
    Aber im Falle von lediglich 4 Funktionen kannst du ja auch ein switch/case gebilde machen.



  • Erzeuge halt einen Vector mit Functoren. Über den kannst du dann iterieren.



  • nurf schrieb:

    Erzeuge halt einen Vector mit Functoren. Über den kannst du dann iterieren.

    Ein vector mit Funktoren wird schwierig, da da lediglich eine Funktion pro Klasse gebraucht werden kann. (Nämlich die des ()-Operators).

    Funktionszeiger (oder halt boost::function o.ä) sind hier die bessere Wahl.



  • Ich versuche das mit den Funktionszeigern zu machen. Ich soll die Funktionen des struct in ein Array packen. Ich habe das noch nicht gemacht. Kannst Du mir das an einem Beispiel mal demonstrieren?

    Viele Dank



  • double fx  (double k) {return sin(k);} // hier eine freie Funktion
    
    int main ()
    {
     double (*f) ( double k ) = &fx;
    
     std::cout << f ( 2.0 );
    }
    

    Prinzipiell so. Du hast aber Memberfunktionszeiger (obwohl das gar nicht nötig ist..überleg mal wieso). Das ist jetzt deine Aufabe mit dem Tutorial hier:
    http://www.newty.de/fpt/index.html

    Den Rest selbst hinzu kriegen. 😉



  • Hallo,
    vielen Dank. Du hast das jetzt mit zwei Funktionen gemacht. Kann man das auch gleich mit einer machen, also direkt so:

    double *fx(double k) {return sin(k);};
    

    Ich habe gerade keinen Compiler. Geht das? Warum hast Du um f Klammern gesetzt.

    Vielen dank



  • struct schrieb:

    double *fx(double k) {return sin(k);};
    

    Was soll denn eigentlich das Semikolon hinter der Funktionsdefinition?

    bnz



  • Lies dir doch erstmal den link durch!
    Kurz: Das erste ist Funktionsdeklaration (+Definition), das Zweite ist ein Zeiger auf eine Funktion mit bestimmter Signatur. Die Klammer muss da auch rum.
    Aber bitte erst mal lesen, bevor du weiterexperimentierst.



  • Hallo,
    ich habe mir mit Interesse diesen Abschnitt des Artikels durchgelesen:

    http://www.newty.de/fpt/fpt.html#arrays

    Da ich noch nie mit dem Bezeichner typdef gearbeitet habe, möchte ich diesen jetzt auch nicht einführen. Dafür möchte ich mich dann mal eigens hinsetzen und diesen studieren 😉

    Naja, ich habe jetzt das hier geschrieben, doch es gibt ein Problem:

    #include <iostream> 
    #include <cmath> 
    using namespace std; 
    
    double fx  (double k) {return sin(k);}; 
    double fx1 (double k) {return cos(k);};
    double fx2 (double k) {return -sin(k);};
    double fx3 (double k) {return -cos(k);};
    
    int main () 
    {
    	double myFunc1[4] = {NULL};
    	double (*myFunc2[4])(double k) = {NULL};
    
    	myFunc1[0] = myFunc2[0] = &fx; //das funktioniert nicht.
    
    	return 0;
    }
    

    Ich weiß auch ehrlich gar nicht, von welchem Typ mein Array sein soll, da es ja sowieso nur Adressen speichern soll. Warum kompiliert das nicht? Mir wäre das sowieso nicht klar. Ich erstelle ein Array, dass die Adresse der Funktion speichert, um dann die Adresse weiterzureichen. Was soll das? Leider ist auf der Seite nach dem zweizeiligen Kommentar einiges durcheinder gekommen, weshalb ich eure Hilfe brauche.

    Vielen Dank



  • und die Semikolons hinter den funktionsdefintionen kommen weg...



  • mir ist sogar eigentlich klar, warum das nicht funktioniert. myFunc1 müsste ja auch was mit zeigern zu tun haben. daher das typdef auf der gelinkten Seite. Kann man das nicht ohne typdef machen. Was muss ich ändern, damit ich die vier Funktionen in das Array "packen" (bzw. deren Adressen) kann?

    Danke



  • Das zweite Array ist ja in Ordnung. Du bekommst da nur einen Fehler, weil das erste Array halt kein Array von Funktionszeigern ist, sondern lediglich double 's enthält.

    Einfach so:

    myFunc2[0] = &fx;
    

    btw:
    Typedefs sind nicht schwer. Alles, was die machen ist einen komplizierten Typausdruck einen anderen Namen geben. Und das ist vor allem bei Funktionszeiger sehr nützlich, weil alles gleich viel lesbarer wird. Im übrigen kann man ohne typedefs keine Funktionszeiger als Rückgabetypen angeben.



  • void test1() { cout << "eins" << endl; }
    void test2() { cout << "zwei" << endl; }
    void test3() { cout << "drei" << endl; }
    void test4() { cout << "vier" << endl; }
    
    int main() 
    { 
    	typedef void ( *function_t ) ();
    	function_t functions[4];
    
    	functions[0] = test1;
    	functions[1] = test2;
    	functions[2] = test3;
    	functions[3] = test4;
    
    	for( int i = 0; i < 4; i++ )
    		functions[i]();
    
    	cin.get();
    }
    


  • Hallo,
    ahh super! Dann hab' ich es begriffen, wie es läuft. Da ich aber was lernen will, würde ich mich sehr freuen, wenn Ihr mir noch die folgenden Fragen beantworten könnt.

    1.) Wenn ich eine "normale" Funktion definiere wie diese:

    int foo(int i){return i*i;}
    

    dann wird dafür ein bestimmter Speicherplatz reserviertö. Was passiert nun bei dieser Funktion:

    double (*myFunc2[4])(double k) = {NULL};
    

    Wird da auch eine feste Speichergröße reserviert?

    2.) Spricht man hier überhaupt von einer Funktion. Solch ein "Konstrukt" war mir bis jetzt unbekannt. Zum einen habe ich ein Array und zum anderen eine Funktion mit Array. Könntet ihr mir das noch ein bisschen erklären, da ich nicht einfach Code von einer Website übernehmen will ohne sie zu vertehen.

    3.) Könnte man solch ein Funktions - Array auch dynamisch deklarieren?

    Vielen Dank



  • 1. Ja, da wird genau so viel Speicher reserviert, wie es nötig ist für 4 Funktionszeiger. (Das sind ja auch "nur" Zeiger).
    Mit einem Typedef siehst du dann, dass es genau das gleiche ist, wie wenn du ein normales Array von z.B int's anlegst.

    2. Das ist ein Funktionszeiger (function pointer). Das besagt ja nur, dass diese Variable auf eine Funktion zeigt. Und du kannst die Funktion auch aufrufen ohne ihren genauen Namen zu kennen.

    3. Jap, klar.



  • Hallo,
    noch eine Frage. wenn ich jetzt alles in eine struct packe, warum funktioniert das dann nicht:

    struct Sinus
    {
     double fx  (double k) {return sin(k);}
     double fx1 (double k) {return cos(k);}
     double fx2 (double k) {return -sin(k);}
     double fx3 (double k) {return -cos(k);}
    } Sin;
    
    ...
    
    double (*mySin[4])(double k) = {&Sin.fx, &Sin.fx1, &Sin.fx2, &Sin.fx3}; //Die Schreibweise funktionieren nur, wenn die 4 Funktionen klassenlos sin.
    

    vielen Dank



  • Wollte nur noch erwähnen, dass, falls es bei Funktoren bleibt, immer ein "const" eingefügt werden sollte, falls möglich:

    struct TrgSin
    {
     double fx(double k) const {return sin(k);};
     //                  ^^^^^
    };
    

    struct schrieb:

    Hallo,
    noch eine Frage. wenn ich jetzt alles in eine struct packe, warum funktioniert das dann nicht?

    Weil es sich um nicht-statische Elementfunktionen handelt. Zeiger auf solche Funktionen sind nicht mit "normalen" Funktionszeigern kompatibel, weil diese Funktionen noch den zusätzlichen this-Parameter eines bestimmten Typs bekommen (in Deinem Fall ein Zeiger auf TrgSin).

    Die Elementfunktionen im struct bringen Dir eh nichts, wenn Du mit Funktionszeigern arbeiten willst.

    Gruß,
    SP



  • Warum genau? Ich hatte nicht vor, die Ausgabedateien ändern zu lassen? Kannst Du das noch erklären?

    Was mache ich denn bei der struct falsch?

    Danke



  • also die structs sind doch sicher so wie in c und da kannst du keine functionen in ein struct packen sondern nur zeiger auf functionen...

    das ganze muß dann so ausschauen...

    struct Sinus
    {
     double (*fx)(double);
     double (*fx1)(double);
     double (*fx2)(double);
     double (*fx3)(double);
    }mySin;
    

    was willst denn damit?

    double (*mySin[4])(double) = {Sin.fx, Sin.fx1, Sin.fx2, Sin.fx3}; //Die Schreibweise funktionieren nur, wenn die 4 Funktionen klassenlos sin.
    

    hatte den fehler auch letztens in nem proggie, functionen sind bereits zeiger also kannst dir das & schenken, anscheinend macht es aber nichts es mit dazu zu schreiben?

    lg lolo


Anmelden zum Antworten