Announcement

Collapse
No announcement yet.

Recursiver Aufruf des Konstruktors

Collapse
This topic is closed.
X
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Recursiver Aufruf des Konstruktors

    Moin moin

    ich habe folgenden Code erzeugt
    1. Headerdatei
    Code:
      __fastcall TfBon (TComponent* Owner,int  Bon);
    2. CPP
    Code:
    __fastcall TfBon::TfBon(TComponent* Owner,int bon)
      : TForm(Owner)
    {
       AktBon = bon;
       IBQuery1->ParamByName("BONNR")->AsInteger = AktBon;
       IBQuery2->ParamByName("BONNR")->AsInteger = AktBon;
       IBQuery1->Active = true;
       IBQuery2->Active = true;
    
    }
    3. der Aufruf
    Code:
          fBon = new TfBon (this,BonNr);
    Nach diesem Aufruf wird der Konstruktor Recursiv (bis zum Stacküberlauf) aufgerufen.

    Was könnte da falsch laufen ??? (BCB6)

  • #2
    Wozu sind in deinem Konstuktor Parameter die du nicht verwendest?
    TComponent* Owner

    Brauchst du wirklich die Ableitung von TForm(Owner)?? Bon ist ein Fenster????

    Wo steht
    fBon = new TfBon (this,BonNr);
    im Quelltext?
    Christian

    Comment


    • #3
      Ich habe mit datei-> neu ein neues Formular in mein Programm gebracht und fBon genannt.
      Im Hauptfenster erzeuge ich dann das Formular mit new TfForm (this).

      Comment


      • #4
        Im Hauptfenster erzeuge ich dann das Formular mit new TfForm (this).
        Wozu??

        Das Formular wird - wenn du es so wie du beschrieben gemacht hast - bereits von der VCL erzeugt.

        Dies geschieht in der eigentlichen Haupt -CPP Datei die so heisst wie das Projekt. Diese sieht so aus:


        Code:
        //---------------------------------------------------------------------------
        #include <vcl.h>
        #pragma hdrstop
        //---------------------------------------------------------------------------
        USEFORM("Unit1.cpp", Form1);
        USEFORM("Unit2.cpp", Form2);
        //---------------------------------------------------------------------------
        WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
        {
         try
         {
          Application->Initialize();
          Application->CreateForm(__classid(TForm1), &Form1); //<<<< Formular 1
        Application->CreateForm(__classid(TForm2), &Form2);  //<<<< Formular 2
          Application->Run();
         }
         catch (Exception &exception)
         {
          Application->ShowException(&exception);
         }
         catch (...)
         {
          try
          {
           throw Exception("");
          }
          catch (Exception &exception)
          {
           Application->ShowException(&exception);
          }
         }
         return 0;
        }
        //---------------------------------------------------------------------------
        Dort werden die Fenster erzeugt und sind dann vorhanden.
        U
        Üblicherweise arbeitet man dann mit dem 2. Fenster in dem man über "Unit verwenden" das neu erzeugte Fenster einem anderen "bekannt" macht.

        http://www.marquardtnet.info/cecke/q...quicky_15.html

        Die Anzeige erfolgt dann über

        2.Fenster->Show()

        oder

        2.Fenster->ShowModal()

        Das manuelle erzeugen einer Klasse ist nicht notwendig. Sollte es in Ausnahmefällen erforderlich sein, muss die maschinelle automatische Erzeugung in den Optionen unter
        Formulare abgeschaltet werden.

        Du machst es dir etwas schwer, es geht einfacher und bequemer.
        Christian

        Comment


        • #5
          Ich habe natürlich die automatische Erzeugung des Formulares abgeschaltet.

          Der Fehler trat erst auf, nachdem ich einen 2. Konstruktor eingefügt habe. Wenn ich diesen wieder rausnehme, läufts wieder.

          Formulare erzeuge ich übrigens dynamisch, damit beim Programmstart nicht jede Menge Speicher belegt wird, der vielleicht garnicht gebraucht wird.

          Comment


          • #6
            Formulare erzeuge ich übrigens dynamisch, damit beim Programmstart nicht jede Menge Speicher belegt wird, der vielleicht garnicht gebraucht wird.
            Der Logik kann ich nicht folgen. Aber du wirst wohl einen Rechner mit 8 MB Speicher am laufen haben.....

            Was glaubst du nimmt eine Instanz der Fensterklasse an Speicher weg? Die Klasse selbst muss ja da sein, sonst könntest du keine Instanz erzeugen. Des Weiteren wirst du ja wohl das Fenster nicht nur so erzeugen und es wird doch mit ziemlicher Sicherheit im Programm gebraucht. Insofern nicht sinnvoll. Ich komme wahrlich aus einer Zeit wo ma mit Bitleisten arbeitete, aber man kann auch übertreiben.

            Wenn du es dann so machen willst, mach es richtig und lagere die Fenster in eine DLL aus und lade diese dynamisch.

            Ansonsten musst du - wie du ja schon bemerkt hast - darauf achten was du mit den Konstruktoren machst, weil diese sich sonst gegenseitig aufrufen.

            Wieso einfach, wenn es auch kompliziert geht.......
            Christian

            Comment


            • #7
              Ich habe mal gelernt, das man Speicher erst dann belegt, wenn man ihn auch tatsächlich braucht. Wieviel Speicher ein Fenster belegt hängt ja auch damit zusammen, was in dem Fenster so los ist (TMS-Grids belegen ziemlich viel Speicher) Die Klasse selbst ist nicht automatisch da, sie ist nur definiert.

              Wenn ich alles der IDE überlassen würde könnte ich ja auch VisualBasic nehmen.

              Comment


              • #8
                Originally posted by Henri van de Velde View Post
                Ich habe natürlich die automatische
                Formulare erzeuge ich übrigens dynamisch, damit beim Programmstart nicht jede Menge Speicher belegt wird, der vielleicht garnicht gebraucht wird.
                Sehr gut. Dass mache Ich auch selbsverständlich.

                Uebrigens gibt ein konstructor wie

                __fastcall TfBon (TComponent* Owner,int Bon);

                in den C++Builder tatsächich stackueberlaufnde recursive anrufe. Dass
                ist leider schon Jahre so.

                __fastcall TfBon (TComponent* Owner,int Bon, int dummy);

                tut es nicht.

                __fastcall TfBon (int Bon, TComponent* Owner);

                ist auch ok.

                __fastcall TfBon (TComponent* Owner,AnsiString Bon);
                würde auch ok sein.

                Est is nur wenn der zweite Parameter ein int ist und keine weitere Parameter folgen dass dass Stackproblem auftritt.

                Comment


                • #9
                  Danke, das habe ich durch probieren auch schon rausgekriegt, dachte aber, das ich da irgendwas falsch mache.

                  Schönen Tag noch

                  Henri

                  Comment


                  • #10
                    Wieviel Speicher ein Fenster belegt hängt ja auch damit zusammen, was in dem Fenster so los ist (TMS-Grids belegen ziemlich viel Speicher)
                    Logisch leider falsch, denn den Speicherplatz brauchen sie immer wenn sie gebraucht werden. Du willst ja VORHER schon Platz sparen, wenn in dem Fenster noch gar nichts los ist. Du willst ja den Platz der Instanz sparen.
                    Das hat nichts damit zu tun das während der Lebenszeit Speicher genutzt wird.

                    Teile doch mal bitte den Speicherverbrauch mit....und damit die Ersparnis
                    Christian

                    Comment


                    • #11
                      Originally posted by Christian Marquardt View Post
                      Logisch leider falsch, denn den Speicherplatz brauchen sie immer wenn sie gebraucht werden. Du willst ja VORHER schon Platz sparen, wenn in dem Fenster noch gar nichts los ist. Du willst ja den Platz der Instanz sparen.
                      Das hat nichts damit zu tun das während der Lebenszeit Speicher genutzt wird.
                      Mir entgeht was du hier behauptest.

                      Ob jetzt ein formular am Anfang (in WinMain) erzeugt wird oder später wärend 'runtime' mit new gemacht wird, das Speicheverbrauch ist gleich.

                      Aber wer last schon hunderd Formulare am Programstart machen? Kostet nicht nur Speicher aber -schlimmer- Zeit. De benutzer von das Program hat doch auf jeder Moment nur drei bis vier Fenster zugleich offen und wird nicht jedesmahl alle mochliche Fenster nutzen.

                      So new und delete bei bedarf.

                      Uebrigens könen von ein Formular zur Laufzeit mehre Instanzen gemacht werden. Was nutzt es dann das da erst eine gemacht wird? Vielleicht wird sie auch gar niet benötigt.

                      Wenn du 100 Formulare am Anfang machtst kostet dir dass zum Beispiel gleich 100 MB. Wenn du wärend Laufzeit immer nur drei Fenster offen hast kostet dass nur 3 Mb.

                      Comment


                      • #12
                        Ob jetzt ein formular am Anfang (in WinMain) erzeugt wird oder später wärend 'runtime' mit new gemacht wird, das Speicheverbrauch ist gleich.
                        Richtig, aber

                        was in dem Fenster so los ist (TMS-Grids belegen ziemlich viel Speicher)
                        dass hier hat nur Einfluß zur Laufzeit.


                        Wenn du 100 Formulare am Anfang machtst kostet dir dass zum Beispiel gleich 100 MB.
                        Natürlich gleich wieder das Kind mit dem Bade ausschütten:

                        a) habe ich nirgends behauptet NICHT die Fenster dynamisch zu erzeugen (siehe DLL-Hinweis)

                        b) Sicherlich sollte man sich bei hundert Fenster ein paar Gedanken machen

                        c) Bei insgesamt 3 Fenstern kann dieser Faktor vernachlässigt werden

                        Des Weiteren kann ich nicht - wie immer - hellsehen; wie man aus Beitrag 4 ersehen kann, bin ich von einem "Anfängerproblem" ausgegangen. D.h. es besteht überhaupt ein Problem die Fenster anzuzeigen usw. Und warum einem Anfänger nicht den leichten Weg erklären.
                        Christian

                        Comment


                        • #13
                          Dass einzige Problem hier hat Henri in seiner erster Post erzählt

                          fBon = new TfBon (this,BonNr);

                          leitet zur 'stackoverflow'.

                          Ich habe erklärt weshalb dass so ist. (Na ja nicht erklärt aber vermeldet dass es eben so geht).

                          Man muss hier auch- und aleine während laufzeit- operator new benutzen weil C++ Builder niemals in WinMain eine derartige konstructor ausnutzen kan.

                          Erst während Laufzeit kan der konstructor mit den richtigen Parametern -mit new- angerufen werden.

                          So kein Anfängerproblem sondern ein bekannter 'bug' in C++Builder.

                          Comment


                          • #14
                            Danke Hans G

                            und zu dem Beitrag von Christian

                            Auch ein Anfänger sollte von vorneherein (wenn er C++ lernen will) sich mit den Grundlagen der Speicherverwaltung vertraut machen. An sonsten bieten sich andere Programmiersprachen (wie Delphi) an.

                            Gerade wenn man grafische Zusatzkomponenten wie TMS oder (noch schlimmer) DevExpress benutzt, ist dies wichtig. Der Unterschied zwischen statisch und dynamisch erzeugten Fenstern liegt in meinen Fall bei ca. 12 MB. (wenn ich auf DevExpress und TMS verzichte sind es zwar nur 2 MB, das Programm sieht dann allerdings richtig sch... aus.

                            Henri (der nicht glauben kann das er ein Anfänger ist)

                            Comment


                            • #15
                              Auch ein Anfänger sollte von vorneherein (wenn er C++ lernen will) sich mit den Grundlagen der Speicherverwaltung vertraut machen.
                              Es ist doch immer wieder erstaunlich, was ein Anfänger alles gleich können muss...


                              Des Weiteren sei nochmals betont, dass ich hier nicht GEGEN die dynamische Erzeugung gesprochen habe, sondern nur einem vermeintlichen Anfänger das Leben leichter machen wollte.

                              Henri (der nicht glauben kann das er ein Anfänger ist)
                              Ich führe kein Buch der Nutzer hier im Forum anhand dess ich die Erfahrung beurteilen kann. Auch das Ansehen aller Beiträge eines Nutzer ist mir zu zeitaufwendig.

                              Aber dieser Thread hat wieder gezeigt, dass es wenig Sinn hat

                              - Probleme zu hinterfragen
                              - prüfen, worin die Ursache liegt, ggf. bessere, dem Niveau des Nutzers angepasste Lösungen vorschlagen


                              Denke, damit ist das hier abzuschließen
                              Zuletzt editiert von Christian Marquardt; 28.12.2007, 08:37.
                              Christian

                              Comment

                              Working...
                              X