String wiedergeben



  • RussianTux schrieb:

    Der Sinn dieses Posts war es nicht euch meinen String-Typ und dessen Funktionalität vorzustellen...

    Lass es mich mal so ausdrücken: die wahrscheinlichkeit, dass es schlechter als std::string wird geht gegen 1, wenn du nicht einmal Operatorüberladung kennst :). Es gibt Fälle bei denen std::string nicht gut ist. Aber die sind recht speziell.



  • otze schrieb:

    Es gibt Fälle bei denen std::string nicht gut ist. Aber die sind recht speziell.

    Ich dachte std::string wäre allgemein schlecht designt.

    Bei einer "1500 Zeilen lange[n] eigene[n] Stringbearbeitungsbibliothek" gilt das aber wohl genauso.


  • Mod

    Das Design ist bloß doof, da man die ganzen schönen Zeichenkettenalgorithmen an std::string gebunden hat, anstatt freie Funktionen zu machen, die man dann auch mit den Iteratoren anderer Datentypen hätte benutzen können. Das ändert aber nichts da dran, dass der std::string selbst seine Aufgaben ziemlich gut macht.



  • otze schrieb:

    RussianTux schrieb:

    Der Sinn dieses Posts war es nicht euch meinen String-Typ und dessen Funktionalität vorzustellen...

    Lass es mich mal so ausdrücken: die wahrscheinlichkeit, dass es schlechter als std::string wird geht gegen 1, wenn du nicht einmal Operatorüberladung kennst :). Es gibt Fälle bei denen std::string nicht gut ist. Aber die sind recht speziell.

    Um das Zuschalten von noch mehr Bibliotheken zu vermeiden, habe ich mir in meinem eigenem Projekt eine eigene String-Bibliothek mit all den nötigen Funktionen geschrieben, die ich gebraucht habe, außerdem habe ich versucht so viel Speicher wie möglich zu sparen und alle Funktionen und Typen komplett dynamisch geschrieben, natürlich hätte ich auch std::string nehmen können, aber um diese strings so zu bearbeiten wie ich es gebraucht hätte, hätte ich noch andere Bibliotheken dazu schalten müssen, "boost" ist einer der Beispiele, das habe ich vermieden weil meine Philosophie auf kompletter Unabhängigkeit beruht.

    Die Operatoren sind kein wirklich großes Problem gewesen, habe ich jetzt mit eurer Hilfe eingebaut, dafür danke ich euch natürlich, immer mal wieder was neues dazuzulernen ist immer gut, das größte Problem an der ganzen Bibliothek waren wohl die 16 komplexen Bearbeitungsalgorithmen welche genau das erfüllen, was ich brauche.

    Die Klasse habe ich gebraucht um die rohe Arbeit mit "const char" Pointern zu vermeiden, es sollte also so einfach wie std::string zu nutzen sein, dennoch die volle Funktionalität meiner String-lib besitzen.

    Die Funktionen der Klasse bei der Erstellung eines neuen Objektes auf Basis dieser Klasse, werden nicht in den Speicher geladen, was dessen Speicherverbrauch erheblich reduziert. Sobald eine Funktion gebraucht wird, wird diese in den Speicher geladen, ausgeführt und anschließend wieder terminiert.

    Ich kann nicht behaupten, dass diese - wie ihr sagen würdet "nachgebaute" lib - in irgendwelcher hinsicht besser ist als std::string, ich weiß nur, dass die Funktionalität dieses Typs deutlich höher als die des std::strings ist und genau für mein Projekt und Vorhaben zugeschnitten ist.

    Edit:

    SeppJ schrieb:

    Das Design ist bloß doof, da man die ganzen schönen Zeichenkettenalgorithmen an std::string gebunden hat, anstatt freie Funktionen zu machen, die man dann auch mit den Iteratoren anderer Datentypen hätte benutzen können. Das ändert aber nichts da dran, dass der std::string selbst seine Aufgaben ziemlich gut macht.

    Alle 16 Algorithmen sind in meiner Bibliothek komplett unabhängig von der Klasse selbst, die Klasse ist wie oben bereits beschrieben nur zur Arbeitserleichterung gedacht.

    unstrung schrieb:

    otze schrieb:

    Es gibt Fälle bei denen std::string nicht gut ist. Aber die sind recht speziell.

    Ich dachte std::string wäre allgemein schlecht designt.

    Bei einer "1500 Zeilen lange[n] eigene[n] Stringbearbeitungsbibliothek" gilt das aber wohl genauso.

    1500 Zeilen Funktionalität, wie ich oben bereits geschrieben habe, werden keine von diesen Funktionen anfangs in den Speicher geladen, sie können bei bedarf dazu geladen, ausgeführt und wieder terminiert werden, somit spielt es überhaupt keine Rolle wie viele Funktionen die Klasse beinhaltet und wie groß diese Funktionen sind, da immer nur das zur Verfügung gestellt wird, was gerade gebraucht wird, theoretisch hätten selbst 100500 Zeilen mit 100500 Funktionen keinen Einfluss auf den Speicherverbrauch und Ausführungsgeschwindigkeit der lib

    Ich hoffe, ich konnte euch hiermit alle Fragen beantworten, wenn nicht stehe ich natürlich weiterhin offen für weitere Diskussionen 😉

    MfG RusTux



  • Irgendwie.. widersprichst du dir dauernd selber..

    RussianTux schrieb:

    Ich kann nicht behaupten, dass diese - wie ihr sagen würdet "nachgebaute" lib - in irgendwelcher hinsicht besser ist als std::string, ich weiß nur, dass die Funktionalität dieses Typs deutlich höher als die des std::strings ist und genau für mein Projekt und Vorhaben zugeschnitten ist.

    Was denn jetzt? Was genau kann deine Klasse was std::string nicht kann? (Die Frage habe ich schon am Anfang gestellt und du hast sie immer noch nicht beantwortet.)

    RussianTux schrieb:

    Die Funktionen der Klasse bei der Erstellung eines neuen Objektes auf Basis dieser Klasse, werden nicht in den Speicher geladen, was dessen Speicherverbrauch erheblich reduziert. Sobald eine Funktion gebraucht wird, wird diese in den Speicher geladen, ausgeführt und anschließend wieder terminiert.

    W T F 😮 Erklär mal was genau du da gemacht hast.



  • RussianTux schrieb:

    Die Funktionen der Klasse bei der Erstellung eines neuen Objektes auf Basis dieser Klasse, werden nicht in den Speicher geladen, was dessen Speicherverbrauch erheblich reduziert. Sobald eine Funktion gebraucht wird, wird diese in den Speicher geladen, ausgeführt und anschließend wieder terminiert.

    Alle Funktionen einer Klasse sind völlig unabhängig davon, wie viele Objekte der Klasse du erstellt hast, genau einmal im Speicher. Daher ergibt diese Aussage keinen Sinn.



  • cooky451 schrieb:

    Irgendwie.. widersprichst du dir dauernd selber..

    RussianTux schrieb:

    Ich kann nicht behaupten, dass diese - wie ihr sagen würdet "nachgebaute" lib - in irgendwelcher hinsicht besser ist als std::string, ich weiß nur, dass die Funktionalität dieses Typs deutlich höher als die des std::strings ist und genau für mein Projekt und Vorhaben zugeschnitten ist.

    Was denn jetzt? Was genau kann deine Klasse was std::string nicht kann? (Die Frage habe ich schon am Anfang gestellt und du hast sie immer noch nicht beantwortet.)

    RussianTux schrieb:

    Die Funktionen der Klasse bei der Erstellung eines neuen Objektes auf Basis dieser Klasse, werden nicht in den Speicher geladen, was dessen Speicherverbrauch erheblich reduziert. Sobald eine Funktion gebraucht wird, wird diese in den Speicher geladen, ausgeführt und anschließend wieder terminiert.

    W T F 😮 Erklär mal was genau du da gemacht hast.

    1. Ein Beispiel wäre das Splitten eines Strings mithilfe eines Delimiter-Strings, das kann std::string von Grund auf nicht, dafür braucht man widerrum andere Bibliotheken, was für mich nicht infrage kommt, auch bedeutet es viel Schreibarbeit und unübersichtlichen Code.
    Dazu kommen noch diverse Konvertoren und Formatierungswerkzeuge die wichtig für mein Projekt sind...

    2. Assembler, nein Spaß beiseite, dynamische Speicherverwaltung in C++ und Methoden, weiteres kannst du dir selber denken...



  • cooky451 schrieb:

    Irgendwie.. widersprichst du dir dauernd selber..

    Ich widerspreche mir nicht, viel Funktionalität heißt nicht sofort "besser", es kommt natürlich drauf an wie du "besser" in diesem Fall definierst...



  • RussianTux schrieb:

    1. Ein Beispiel wäre das Splitten eines Strings mithilfe eines Delimiter-Strings, das kann std::string von Grund auf nicht, dafür braucht man widerrum andere Bibliotheken, was für mich nicht infrage kommt, auch bedeutet es viel Schreibarbeit und unübersichtlichen Code.
    Dazu kommen noch diverse Konvertoren und Formatierungswerkzeuge die wichtig für mein Projekt sind...

    Ich weiß zwar nicht was du mit "splitten mit einem Delimiter-String" genau meinst, aber das hört sich ganz stark nach Kandidaten für freie Methoden an.

    RussianTux schrieb:

    2. Assembler, nein Spaß beiseite, dynamische Speicherverwaltung in C++ und Methoden, weiteres kannst du dir selber denken...

    Nein, überhaupt nicht. Das macht keinen Sinn. Gar nicht. Poste mal Beispielcode.



  • cooky451 schrieb:

    RussianTux schrieb:

    2. Assembler, nein Spaß beiseite, dynamische Speicherverwaltung in C++ und Methoden, weiteres kannst du dir selber denken...

    Nein, überhaupt nicht. Das macht keinen Sinn. Gar nicht. Poste mal Beispielcode.

    In den Methoden der Klasse String werden dynamische Klassen (1 Klasse mit je 1 Methode welche den Algorithmus beinhaltet) gebildet

    class Funktion
    {
    public:
        static <return_value> Algorithmus(parameter)
        {
            //funktionalität
            return <return_value>;
        }
    };
    
    class String
    {
    public:
    
        Methode(<parameter>)
        {
            Funktion* func = new Funktion;
            <return_value> =  func->Algorithmus(<parameter>);
            delete func;
            return <return_value>;
        }
    };
    

    Sobald eine Methode des Strings aufgerufen wird, wird ein Abbild der Funktion in den Speicher geladen, ausgeführt und anschließend aus dem Speicher gelöscht.
    Eigentlich ganz einfach, kann man aber natürlich auch an etwas nicht gedacht haben, aber eigentlich sollte es so einwandfrei funktionieren.



  • RussianTux schrieb:

    1. Ein Beispiel wäre das Splitten eines Strings mithilfe eines Delimiter-Strings, das kann std::string von Grund auf nicht

    Du hast erst mal recht, dass es so etwas wie pythons split() nicht direkt gibt. Aber in 99% der Fälle braucht man auch keinen physischen Schritt, sondern nur wissen, von wo bis wo der nächste Abschnitt geht, damit man darauf arbeiten kann. Und wenn man ihn braucht, dann ist das noch lange kein Argument gegen std::string, weil er alle Funktionalität zusammen mit der STL bietet, um sich so etwas zu bauen. Dafür war er gedacht.

    quick& dirty:

    std::vector<std::string> split(std::string const& str, std::string const& delimiter){
        std::vector<std::string> tokens;
        std::string::const_iterator pos = str.begin();
        while(pos < str.end()){
            std::string::const_iterator tokenend = std::search( pos,str.end(), delimiter.begin(),delimiter.end());
            tokens.push_back(std::string(pos,tokenend);
            pos = tokenend+delimiter.size();
        }
        return tokens;
    }
    

    Dazu kommen noch diverse Konvertoren und Formatierungswerkzeuge die wichtig für mein Projekt sind...

    sicher kann man das alles auch trivial mit der Standardbibliothek in einen 5-Zeiler verwandeln.

    //edit formatierung...

    //edit2

    Sobald eine Methode des Strings aufgerufen wird, wird ein Abbild der Funktion in den Speicher geladen, ausgeführt und anschließend aus dem Speicher gelöscht.
    Eigentlich ganz einfach, kann man aber natürlich auch an etwas nicht gedacht haben, aber eigentlich sollte es so einwandfrei funktionieren.

    Nein, so funktioniert C++ nicht. Der Code ist immer im Speicher. Und zwar exakt 1x. Das einladen passiert zum Programmstart und endet beim Ende des Programmes (außer du machst gruseliges explizites dll handling und selbst da wäre ich mir nicht sicher.).

    //edit3 Schleifenbedingung umgewandelt. manchmal sollte man länger als 1 Minute nachdenken 😃



  • Funktionscode liegt im statischen Speicher. Ist ja auch ganz logisch. Wo soll denn der Algorithmus herkommen, nachdem du den Speicher reserviert hast? Ja, das funktioniert, aber es hat nicht den Effekt den du dir vorstellst. Zumal du auch einfach ein Objekt der Klasse erstellst, das dann dann schon über zwei Ebenen nichts mehr miteinander zu tun. Das Einzige was du hier erreichst, ist ein unglaublich großer Overhead durch new und delete, der das Ganze wahrscheinlich 100-1000 mal langsamer macht als vorher.

    Gut, dass wir da noch mal drüber schreiben konnten. 😉

    Und warum deine Stringmethoden keine freien Funktionen sein können, hast du auch noch nicht beantwortet.



  • cooky451 schrieb:

    Funktionscode liegt im statischen Speicher. Ist ja auch ganz logisch. Wo soll denn der Algorithmus herkommen, nachdem du den Speicher reserviert hast? Ja, das funktioniert, aber es hat nicht den Effekt den du dir vorstellst. Zumal du auch einfach ein Objekt der Klasse erstellst, das dann dann schon über zwei Ebenen nichts mehr miteinander zu tun. Das Einzige was du hier erreichst, ist ein unglaublich großer Overhead durch new und delete, der das Ganze wahrscheinlich 100-1000 mal langsamer macht als vorher.

    Gut, dass wir da noch mal drüber schreiben konnten. 😉

    Und warum deine Stringmethoden keine freien Funktionen sein können, hast du auch noch nicht beantwortet.

    Doch habe ich,

    RussianTux schrieb:

    Alle 16 Algorithmen sind in meiner Bibliothek komplett unabhängig von der Klasse selbst, die Klasse ist wie oben bereits beschrieben nur zur Arbeitserleichterung gedacht.

    Nur das Problem, welches ich befürchtet habe, war, dass wenn ich die Funktion einfach in der String-Klasse als Methode deklarieren würde:

    <Typ> Algorithmus1(<parameter>)
    {
        //funktionalität...
        return <Typ>;
    }
    
    <Typ> Algorithmus2(<parameter>)
    {
        //funktionalität...
        return <Typ>;
    }
    //und noch viele weitere Algorithmen...
    
    class String
    {
    private:
        const char* Zeile;
    public:
        //methoden
        <Typ> Methode1(<parameter>)
        {
            return Algorithmus1(Zeile, <parameter>);
        }
        <Typ> Methode2(<parameter>)
        {
            return Algorithmus2(Zeile, <parameter>);
        }
        //und noch viele weitere Methoden...
    };
    

    und später viele Objekte, also Strings, auf Basis dieser Klasse erstellen würde, die Funktionalität eines jeden Objektes jeweils 1 mal in den Speicher geladen werden würde, bei 5 kleinen Strings wären es also 16*5 große Algorithmen und das ist ineffizient, oder hab ich beim Lernen mal wieder nicht aufgepasst?



  • RussianTux schrieb:

    Sobald eine Methode des Strings aufgerufen wird, wird ein Abbild der Funktion in den Speicher geladen, ausgeführt und anschließend aus dem Speicher gelöscht.
    Eigentlich ganz einfach, kann man aber natürlich auch an etwas nicht gedacht haben, aber eigentlich sollte es so einwandfrei funktionieren.

    Ich frage mich immer wieder, wie manche Leute auf manche Ideen kommen. Und sich dann auch noch so sicher sind, dass sie versuchen andere zu belehren.

    Wie cooky451 schon geschrieben hat: das funktioniert sich nicht so wie du denkst.

    Die Funktion wird in deinem Beispiel nicht dynamisch geladen und dann wieder entladen.

    Verschiedene Betriebssysteme handhaben das z.T. etwas unterschiedlich, d.h. es kann sein dass manche Code-Teile wirklich erst später geladen werden. Wie das im Detail abläuft und was es für Auswirkungen hat ist etwas zu komplex um es hier zu erklären.

    Aber lass dir gesagt sein: mit dem "new + delete" in beinem Beispiel kannst du diesen Prozess nicht beeinflussen. Es würde mit einer freien Funktion genau so passieren oder genau so nicht passieren. Das einzige was das "new + delete" macht, ist CPU-Zeit zu verschwenden.



  • RussianTux schrieb:

    Alle 16 Algorithmen sind in meiner Bibliothek komplett unabhängig von der Klasse selbst, die Klasse ist wie oben bereits beschrieben nur zur Arbeitserleichterung gedacht.

    Und was macht sie leichter und was hindert dich daran freie Funktionen mit der gleichen Aufgabe für std::string zu schreiben?

    RussianTux schrieb:

    und später viele Objekte, also Strings, auf Basis dieser Klasse erstellen würde, die Funktionalität eines jeden Objektes jeweils 1 mal in den Speicher geladen werden würde, bei 5 kleinen Strings wären es also 16*5 große Algorithmen und das ist ineffizient, oder hab ich beim Lernen mal wieder nicht aufgepasst?

    Lies doch die Beiträge hier. Funktionen liegen im statischen Speicher undzwar genau einmal, und da kannst du noch so viel mit new zaubern, daran wirst du nichts ändern. dlls können das vielleicht, aber das liegt völlig außerhalb der Sprache.

    Hättest du meinen Beitrag oben ordentlich gelesen, hättest du das auch gemerkt.



  • cooky451 schrieb:

    RussianTux schrieb:

    Alle 16 Algorithmen sind in meiner Bibliothek komplett unabhängig von der Klasse selbst, die Klasse ist wie oben bereits beschrieben nur zur Arbeitserleichterung gedacht.

    Und was machen sie leichter und was hindert dich daran freie Funktionen mit der gleichen Aufgabe für std::string zu schreiben?

    RussianTux schrieb:

    und später viele Objekte, also Strings, auf Basis dieser Klasse erstellen würde, die Funktionalität eines jeden Objektes jeweils 1 mal in den Speicher geladen werden würde, bei 5 kleinen Strings wären es also 16*5 große Algorithmen und das ist ineffizient, oder hab ich beim Lernen mal wieder nicht aufgepasst?

    Lies doch die Beiträge hier. Funktionen liegen im statischen Speicher undzwar genau einmal, und da kannst du noch so viel mit new zaubern, daran wirst du nichts ändern. dlls können das vielleicht, aber das liegt völlig außerhalb der Sprache.

    Hättest du meinen Beitrag oben ordentlich gelesen, hättest du das auch gemerkt.

    Ok ich verstehe, pro Klasse werden also genau 1 mal alle Funktionen in den statischen Speicher geschrieben und jedes darauf basierende Objekt, wendet sich dann an diesen statischen Speicher um eine Methode aufzurufen, richtig?

    wenn das so ist, ist dieser Aufwand also gar nicht erst nötig und die Klasse kann ganz einfach geschrieben werden:

    <Typ> Algorithmus1(const char* string, <Parameter>)
    {
        //Funktionalität...
        return <Typ>;
    }
    
    <Typ> Algorithmus2(const char* string, <Parameter>)
    {
        //Funktionalität...
        return <Typ>;
    }
    
    // alle weiteren 14 Algorithmen...
    
    class String
    {
    private:
        const char* Zeile;
    public:
        <Typ> Methode1(<Parameter>)
        {
            return Algorithmus2(Ziele, <Parameter>);
        }
    
        <Typ> Methode2(<parameter>)
        {
            return Algorithmus2(Zeile, <Parameter>);
        }
        //alle restlichen 14 Methoden...
    };
    

    Und selbst gleichzeitiges Existieren von mehreren Dutzend Objekten nach der Klassenvorlage würde die Anzahl der Funktionen im Speicher nicht erhöhen, korrekt?



  • [quote="RussianTux"]

    otze schrieb:

    Um das Zuschalten von noch mehr Bibliotheken zu vermeiden, habe ich mir in meinem eigenem Projekt eine eigene String-Bibliothek mit all den nötigen Funktionen geschrieben, die ich gebraucht habe ... das habe ich vermieden weil meine Philosophie auf kompletter Unabhängigkeit beruht.

    Ich möchte hier nicht auf den sonstigen Unsinn eingehen, den du von dir gegeben hast, das haben schon andere getan. Aber allein diese Aussagen finde ich nochmal erwähnenswert. Das ist das Not invented here Syndrom. Ganz übel, ich hoffe du kommst irgendwann davon weg. Das führt mit der Zeit zu unglaublichen Problemen. Wenn du sagst, du willst eine eigene String Klasse schreiben, um C++ zu lernen, ok, ist vielleicht nicht das beste Übungsprojekt, aber meinetwegen. Aber alles andere sollte man sich ganz schnell abgewöhnen. Es gibt in der Tat manchmal Fälle, wo es besser ist, von Fremdbibliotheken unabhängig zu sein, oder eigene zu schreiben, aber die Fälle sind extrem selten und dann muss man schon ganz genau wissen, warum man das tut.



  • RussianTux schrieb:

    Ok ich verstehe, pro Klasse werden also genau 1 mal alle Funktionen in den statischen Speicher geschrieben und jedes darauf basierende Objekt, wendet sich dann an diesen statischen Speicher um eine Methode aufzurufen, richtig?

    Ja, mehr oder weniger. Aber nicht pro Klasse oder pro sonst was. Methoden und freie Funktionen sind hier gleich. Wann wie und wo Code in den Speicher geladen wird kannst du so nicht beeinflussen.

    RussianTux schrieb:

    wenn das so ist, ist dieser Aufwand also gar nicht erst nötig und die Klasse kann ganz einfach geschrieben werden:

    Noch besser: Der Aufwand ist gar nicht erst nötig und man könnte einfach std::string nutzen.

    Ich kann wirklich verstehen, wenn man nicht von externen Bibliotheken abhängen will. Ja, wirklich, ich kann das schon fast zu gut verstehen. Aber die Standardbibliothek nicht nutzen? 😮 Da sollte man schon sehr gute Gründe haben.



  • cooky451 schrieb:

    RussianTux schrieb:

    Ok ich verstehe, pro Klasse werden also genau 1 mal alle Funktionen in den statischen Speicher geschrieben und jedes darauf basierende Objekt, wendet sich dann an diesen statischen Speicher um eine Methode aufzurufen, richtig?

    Ja, mehr oder weniger. Aber nicht pro Klasse oder pro sonst was. Methoden und freie Funktionen sind hier gleich. Wann wie und wo Code in den Speicher geladen wird kannst du so nicht beeinflussen.

    RussianTux schrieb:

    wenn das so ist, ist dieser Aufwand also gar nicht erst nötig und die Klasse kann ganz einfach geschrieben werden:

    Noch besser: Der Aufwand ist gar nicht erst nötig und man könnte einfach std::string nutzen.

    Ich kann wirklich verstehen, wenn man nicht von externen Bibliotheken abhängen will. Ja, wirklich, ich kann das schon fast zu gut verstehen. Aber die Standardbibliothek nicht nutzen? 😮 Da sollte man schon sehr gute Gründe haben.

    Ich hab eigene Methoden zur Bearbeitung von Textzeilen, jetzt brauche ich nur einen Puffer für den Text, Opeartorenüberladung inerhalb der Klasse und Methoden die auf Funktionen verweisen...

    Wozu brauche ich die std::string lib? Ich sehe keinen einzigen Grund dafür



  • RussianTux schrieb:

    Wozu brauche ich die std::string lib? Ich sehe keinen einzigen Grund dafür

    Gut gewarteter, relativ effizienter Code der extrem gut getestet ist und unglaublich gutes Wiederverwendungspotenzial hat? Na, du hast recht, gibt keinen Grund.

    //edit wieviele Zeilen hat eigentlich deine Splitfunktion? Also meine hat 10.


Anmelden zum Antworten