Dynamische Parameterübergabe & Inline Containers



  • Hi!

    Wie schreibe ich eine Funktion der Form "sprintf" ?

    Diese kann ja beliebig viele Parameter übernehmen. Wie realisiere ich sowas?

    MfG



  • FAQ



  • Geht nicht. Theoretisch müsste ich doch einen leeren Funktionsrumpf einfach so aufrufen können.

    Da kommt aber immer ne Fehlermeldung zur Laufzeit.

    MfG



  • Wie sieht denn Deine Funktion aus?
    Und was für einen Fehler genau gibt es dazu?
    Ein "Geht nicht" ist enorm aufschlussreich



  • void multiFocus(BITMAP * sur, int editCol, int blitCol, int noOfArgs, CEditBox otherBox, ...)
    {
    	BITMAP * temp = create_bitmap (sur->w, sur->h);
    	blit(sur, temp, 0, 0, 0, 0, sur->w, sur->h);
    
    	CEditBox * box = new CEditBox[noOfArgs];
    
    	box[0] = otherBox;
    
    	va_list arglist; 
    	va_start(arglist, otherBox);	
    
    	for (int i = 1; i < noOfArgs; i++)
    		box[i] = va_arg(arglist, CEditBox);
    
    	va_end(arglist);
    	delete [] box;
    }
    

    Hab das jetzt mal stark vereinfacht. Schon hier kommt ein Fehler. Aufruf:

    BITMAP * backBuffer = create_bitmap(300, 200);
    CEditBox size_xBox, size_yBox;
    multiFocus(backBuffer, COLOR_YELLOW, COLOR_WHITE, 2, size_xBox, size_yBox);
    

    Ich glaub der hat irgendein Problem damit, das die dynamischen Parameter meine eigene CEditBox-Klasse betreffen.

    Muss man IN der Klasse irgendwas beachten?



  • Bei printf musst Du wenn ich mich recht entsinne referenzen übergeben, ich denke das zählt für eigene Unbegrenzt-Param-Funktionen wohl auch.



  • Wenn ich Referenzen übergeben, dauert es 4-5 Sekunden länger (ohne was zu machen) bis der dicke Fehler kommt und das Programm abschmiert.

    Hab auch ma n Kopierkonstruktor für CEditBox angelegt - hat nix geholfen.

    MfG

    Edit: Gesagt sei noch, dass die multiFocus-Funktion in einer Endlosschleife läuft.



  • Funktionen mit unbestimmter Parameteranzahl funktionieren nicht mit non built-ins - sprich mit klassen!

    wie waers mit folgendem: http://www.moderncppdesign.com/publications/inline_containers.html



  • Danke. Ich gucks mir ma an.

    Gibt es einen bestimmten Grund, warum das nicht mit selbstgeschriebenen Klassen geht?

    Ich habs jetzt mal mit nem Array versucht:

    while(true)
    {
    ....
    boxArray = new CEditBox[2];
    boxArray[0] = size_xBox;
    boxArray[1] = size_yBox;
    multiFocus(backBuffer, COLOR_YELLOW, COLOR_WHITE, 2, boxArray);
    delete [] boxArray;
    ....
    }
    

    Die multiFocus-Funktion sieht nun so aus:

    void multiFocus	(BITMAP * sur, int editCol, int blitCol, int noOfArgs, CEditBox * boxArray) {}
    

    Es steht noch nix drinne. Trotzdem schmiert mir das Programm mit einer Fehlermeldung ab. Zwar nicht sofort, aber nach ca 5 Sekunden.

    MfG



  • Hi!

    void multiFocus(BITMAP * sur, int editCol, int blitCol, int noOfArgs, CEditBox & otherBox, ...)
    {
    	BITMAP * temp = create_bitmap (sur->w, sur->h);
    	blit(sur, temp, 0, 0, 0, 0, sur->w, sur->h);
    
    	CEditBox * box[500];
    
    	box[0] = &otherBox;
    
    	va_list arglist; 
    	va_start(arglist, otherBox);	
    
    	for (int i = 1; i < noOfArgs; i++)
    		box[i] = & (va_arg(arglist, CEditBox));
    
    	va_end(arglist);
    }
    

    Nun ein neues Problem. Ich habe folgenden Aufruf:

    multiFocus(backBuffer, COLOR_YELLOW, COLOR_WHITE, 2, size_xBox, size_yBox);
    

    Nun ist in der Funktion aber der Fall, dass box[0] auf size_xBox zeigt (richtig), aber box[1] auf descrBox (falsch, wurde aber zuvor vereinbart) zeigt.

    Sind nun die CEditBox-Objekte falschrum im Speicher angeordnet oder was erklärt dieses Verhalten des "Rückwärtsgehens im Speicher" ?

    Ich hab folgende CEditBox-Objekte in dieser Anordnung deklariert:

    CEditBox nameBox (30, 50, 260, 20, courier); 
    	CEditBox descrBox (30, 90, 260, 60, medium); 
    	CEditBox size_xBox (130, 110, 20, 20, courier);
    	CEditBox size_yBox (170, 110, 20, 20, courier);
    	CEditBox timeBox (135, 80, 30, 20, courier);
    

    MfG



  • Warum übergibst du kein Array oder einen vector?

    Shade of Mine hat doch bereits gesagt, dass variable Parameterlisten nur mit built-ins funktionieren, also nicht mit Klassen (okay, mit Zeigern klappt es vielleicht).
    Aber man benutzt in C++ keine variablen Parameterlisten, es gibt nämlich viel bessere und vor allem typsichere Methoden.

    btw: Woher weißt du, dass die Funktion nach 5 Sekunden abschmiert? Das erscheint mir etwas weit hergeholt, dass Windows mit der Schutzverletzung 5 Sekunden wartet. Tipp: Geh die Funktion mal im Debugger durch, dann siehst du ganz genau welche Variablen stimmen und welche nicht.



  • Alexandrescus Inline Container scheinen mir dafuer uebrigens praedestiniert zu sein.



  • Diese Inline-Container hab ich aber ned verstanden...

    Ist das jetzt eine extra Klasse oder wie? Ich hab mir das Listing mal angeschaut. Sehr verwirrend, sry. 😞

    MfG



  • Du ladest dir die source runter.

    Und dann schreibst du einfach:

    #include "InlineContainer.h"
    um die Container einzubinden.

    Der rest ist simpel:

    void foo(std::vector<Control> const& edits)
    {
      std::vector<Control>::iterator i=edits.begin();
      std::vector<Control>::iterator end=edits.end();
    
      while(i!=end)
      {
        i->update();
        ++i;
      }
    }
    
    //der aufruf:
    foo(make_vector(hwnd1)(hwnd2)(Control(foo))(someFunction()));
    

    was hast du denn genau nicht verstanden? die templates? die kannst du dir ja wegdenken (siehe mein beispiel) - allerdings darfst du dann halt immer nur make_vector verwenden...



  • btw, @Saiyaman: Bitte ändere nicht laufend das Topic, ohne dazuzuschreiben was es vorher war. So etwas fördert nicht gerade den Wiedererkennungswert.



  • OK. Ich hab das Topic verallgemeinert.

    MfG



  • @Shade of Mine

    Was genau ist dieses "i" ? Ein Zeiger?

    void multiFocus (BITMAP * sur, int editCol, int blitCol, int noOfArgs, std::vector<CEditBox> &edits)
    {
    	BITMAP * temp = create_bitmap (sur->w, sur->h);
    	blit(sur, temp, 0, 0, 0, 0, sur->w, sur->h);
    
    	CEditBox * box[500];
    	int j = 0;
    
    	std::vector<CEditBox>::iterator i   = edits.begin(); 
    	std::vector<CEditBox>::iterator end = edits.end(); 
    
    	while(i!=end)
    		box[j++] = i++;
    };
    

    Zeigt das Box-Array von Pointern jetzt immer auf eine EditBox ?

    Aufruf:

    multiFocus(backBuffer, COLOR_YELLOW, COLOR_WHITE, 3, make_vector(size_xBox)(size_yBox));
    

    MfG



  • Saiyaman schrieb:

    Was genau ist dieses "i" ? Ein Zeiger?

    Ein iterator - siehe deine Lieblingsdoku ueber die STL
    Ein iterator ist aber im Prinzip ein Zeiger (man beachte: im Prinzip)

    Zeigt das Box-Array von Pointern jetzt immer auf eine EditBox ?

    Uebergib dann besser auch nur Zeiger.

    zB:

    typedef std::vector<CEditBox*> EditBoxArray;
    
    void multiFocus (BITMAP * sur, int editCol, int blitCol, int noOfArgs, EditBoxArray const& edits)
    {
        BITMAP * temp = create_bitmap (sur->w, sur->h);
        blit(sur, temp, 0, 0, 0, 0, sur->w, sur->h);
    
        CEditBox * box[500];
        int j = 0;
    
        EditBoxArray::iterator i   = edits.begin(); 
        EditBoxArray::iterator end = edits.end(); 
    
        while(i!=end)
        {
          box[j++] = *i;
          ++i;
        }
    };
    
    //aufruf:
    multiFocus(backBuffer, COLOR_YELLOW, COLOR_WHITE, 3, make_vector(&size_xBox)(&size_yBox));
    


  • i ist ein Iterator. Ein Zeiger ist auch ein Iterator. (Iterator ist sozusagen die Abstraktion)

    Saiyaman schrieb:

    Zeigt das Box-Array von Pointern jetzt immer auf eine EditBox ?

    /edit: Jetzt versteh ich's

    /edit: menno, zu spät...



  • Vielen Dank! Hat alles wunderbar geklappt!

    Ein Hoch auf die "Inline Container" !! Hip, Hip!!

    😃

    MfG


Anmelden zum Antworten