Fehlermeldung wenn Instanz ohne new erstellt wird



  • @Schlangenmensch

    danke Dir. Noch mal zum Delegieren:

    Der Aufruf in der eigenen Klasse sieht so aus:

            // in meiner Class Response
            void start_html(){
                string filename = BIN["default"]["tmpldir"]+"/start_html.chtml";            
                start_html_buffer = my::read_file(filename);
                start_html_buffer = render( start_html_buffer, STASH ); // delegiert
            };
    

    Das heißt, daß die TE-Instanz die hinter der delegierten Methode steckt in der eigenen Methode gar nicht sichtbar ist. Ergo kann ich da auch kein delete aufrufen weil ich den Pointer gar nicht habe. Von daher darf die TE-Instanz nicht per new erstellt werden.

    Viele Grüße!



  • @_ro_ro
    Und wo wir uns den Code schon mal etwas genauer ansehen:

    Hast du dich mit den Möglichkeiten der Parameterübergabe mal beschäftigt? Sagen dir Referenzen etwas? Deine render Funktion erzeugt beim Aufruf Kopien der Parameter, was insbesondere bei std::map schnell teuer werden kann. Lies dich bitte mal in die Thematik pass by value vs. pass by reference ein.
    Ich nehme mal an, dass templ und stash nur Kontextinformationen enthalten und nicht beschrieben werden, daher könntest du sie aus Performance-Gründen als const-reference übergeben:

    std::string render( std::string const& templ, std::map<string,string> const& stash){
       Templating::TE te( templ, stash );
       return te.render();
    };
    

    Wenn die Funktion TE::render() als const-deklariert ist kann man auch

    std::string render( std::string const& templ, std::map<string,string> const& stash){
       Templating::TE const te( templ, stash );
       return te.render();
    };
    

    schreiben. Und wofür steht TE eigentlich? Finde ich als Klassennamen wenig aussagekräftig, das stört mich schon.

    Überhaupt solltest du dich mit dem const-Konzept auseinandersetzen und möglichst alles als const deklarieren, was nach der Initialisierung nicht mehr verändert wird. Und auch das Wiederverwenden von lokalen Variablen ist allgemein ein Codesmell:

    void start_html(){
       // der Dateiname wird sich während der Bearbeitung wohl nicht mehr ändern, daher kann man ihn const machen
       std::string const filename = BIN["default"]["tmpldir"]+"/start_html.chtml";            
    
       // was genau passiert hier? Warum ist start_html_buffer erst das eine, und dann was anderes?
       start_html_buffer = my::read_file(filename);
       start_html_buffer = render( start_html_buffer, STASH ); // delegiert
    
       // besser:
       std::string const html_template = my::read_file(filename);
       start_html_buffer = render( html_template , STASH ); // delegiert
    };
    


  • @DocShoe

    Ja natürlich, Übergabe per Referenz, schon korrigiert, danke für den Hinweis. TE steht für TemplatingEngine, dafür habe ich einen dedizierten Namespace "Templating" und von daher ist dann auch der Aufruf selbsterklärend

       Templating::TE;
    

    Viele Grüße!



  • @_ro_ro sagte in Fehlermeldung wenn Instanz ohne new erstellt wird:

    @DocShoe

    Ja natürlich, Übergabe per Referenz, schon korrigiert, danke für den Hinweis. TE steht für TemplatingEngine, dafür habe ich einen dedizierten Namespace "Templating" und von daher ist dann auch der Aufruf selbsterklärend

       Templating::TE;
    

    Viele Grüße!

    Finde ich nicht, aber gut. Renderer oder RenderingEngine fände ich besser (nachdem, was ich bisher verstanden habe).



  • @DocShoe

    eigentlich so

    Templating::Simple; // Einfache Platzhalter
    Templating::Loop;    // Loops und Platzhalter
    

    aber ich sehe schon, Ihr bringt mich ganz schön auf Trab 😉

    Viele Grüße!



  • @Schlangenmensch sagte in Fehlermeldung wenn Instanz ohne new erstellt wird:

    Bei
    Templating::TE te = Templating::TE(templ, stash);

    Wird theoretisch, auf der rechten Seite ein Objekt erstellt und dann dem Objekt auf der linken Seite zugewiesen und dafür kopiert. Mit "aktuelleren" (ab C++11) Sprachstandards haben wir "Move Semantics". D.h. es wird nicht unbedingt kopiert, sondern, wenn ein Move Assignment existiert (wird häufig vom Compiler zur Verfügung gestellt), wird das Objekt einfach an die richtige Stelle "geschoben" und fertig.

    Nee. da wird und wurde schon immer der Konstruktor -und nur der Konstruktor- aufgerufen.



  • @Jockelx sagte in Fehlermeldung wenn Instanz ohne new erstellt wird:

    @Schlangenmensch sagte in Fehlermeldung wenn Instanz ohne new erstellt wird:

    Bei
    Templating::TE te = Templating::TE(templ, stash);

    Wird theoretisch, auf der rechten Seite ein Objekt erstellt und dann dem Objekt auf der linken Seite zugewiesen und dafür kopiert. Mit "aktuelleren" (ab C++11) Sprachstandards haben wir "Move Semantics". D.h. es wird nicht unbedingt kopiert, sondern, wenn ein Move Assignment existiert (wird häufig vom Compiler zur Verfügung gestellt), wird das Objekt einfach an die richtige Stelle "geschoben" und fertig.

    Nee. da wird und wurde schon immer der Konstruktor -und nur der Konstruktor- aufgerufen.

    Dann sollte @_ro_ro den kompletten code zeigen an dem der fehler tatsächlich auftritt.
    Denn aktuell scheint es, dass er nur seine Vermutung welche stelle das problem verursacht haben könnte gepostet hat



  • @firefly

    na, bisher habe ich soweit alles verstanden. Meine Instanzen erhalte ich ganz ohne new und Pointerei jetzt so

      CGI cgi;
      Response response;
    
              // Delegation Instanz Templating::Simple
            string render(const string &templ, const map<string,string> &stash){
                Templating::Simple te = Templating::Simple(templ, stash);
                return te.render();
            };
    

    und übergeben werden Referenzen. const habe ich ergänzt wo es angebracht ist, auch in den darunterliegenden Klassen die ich auch umbenannt habe damit der Name schonmal was sagt.

    Vielen Dank euch allen !



  • @Jockelx Ja, es wird keine Zuweisung ausgeführt, sondern der Copy ctor aufgerufen. Andernfalls wird aber das Objekt direkt initialisiert.
    Siehe copy initialization und direct initialization



  • @Schlangenmensch

    Aha, jetzt verstanden

            // Delegation Instanz der TE-Klasse
            string render(const string &templ, const map<string,string> &stash){
                Templating::Simple te(templ, stash);
                return te.render();
            };
    

    und jetzt Feierabend 😉


Anmelden zum Antworten