Eigenen Typ "String" in c++ deffinieren - wie?



  • Simon2 schrieb:

    bastl schrieb:

    ...gib dir mal den Wert c_string[0] aus.

    Genau, sobald du einen Zeiger hast geht das mit c-string nicht mehr bzw. schwerer, da der c-String seine Länge nicht anthält sondern sie mit 0 als Ende markiert....

    Also nun bin ich genauso verwirrt und neugierig wie Dravere ...
    Kann es sein, dass Du von C-Strings sprichst, wo er von std::string (etwas ganz Anderes) spricht?

    Ich dachte, daß allseits bekannt ist wie Strings in C, C++ verarbeitet werden.
    Also C-Strings sind vom typ char abgeleitet genauso wie std::string oder <<char str[] = "text">>, nur daß <<char str[]>> deutlich mehr Freiheiten hat als std::string (ist eine Klasse).

    (Nachfolgendes ist nicht 100%ig sicher)
    Nach jeder Veränderung eines std::string wird die Länge des Strings beim Aufruf von sdt::length() neu berechnet mit oder ähnlich

    int i=0
    while( string[i]!=0 ) i++;
    return i;
    

    .

    Wenn ein String an Position 0 keine Längenangabe hat, dann führt er auch seine Länge nicht mit sich !!!

    Dravere schrieb:

    std::string str = "hello";
    

    hello wird als c-String zu <<hello0>>, str[0] = h bzw. 104 und somit nicht 5 oder 6.
    Hat man nun einen std::string, der nicht const ist in einer for-Schleife:

    for( int i=0; i<str.length(); i++)
    

    so wird jedesmal die Länge der Abbruchbedingung durch einen Funktionaufruf übermittelt und nicht direckt durch eine Speicherangabe (wie bei pascal String (char)str[0]).
    In c++ bedeutet dann gutes programmieren:

    int l = str.length();
    for( int i=0; i < l; i++)
    

    wobei eine Längenänderung (z.B Teile ersetzen) des Strings und ein anschließender Zugriff über eine sdt:: Funktion in der Schleife nicht vorkommen darf, sonst ist die Mühe umsonst und die Länge wird neu berechnet.
    (Ende des <<Nachfolgendes ist nicht 100%ig sicher>>)

    Ganz im gegensatz zu Pascal Strings wo man selbst dafür sorgen muss mit new das array zu erweitern und die Länge neu eintragen kann, wenn man will, oder entsprechende Member schreibt.
    Das erlaubt unheimliche Performance gegenüber c-Strings, die nicht entwickelt wurden um in einer for Schleife auf ihre Elemente zuzugreifen.

    Für die die jetzt anfangen zu grübeln:
    Sobald ich die Länge zu einem String speichere auch in einer Extra Variablen, habe ich das Prinzip Pascal String und nichts anderes, nur in einer etwas freieren Version. Kompakter und präziser ist es halt, wenn man die Längenangabe direkt im String speichert. Ob man jetzt 1, 4 oder 8 Byte für die Längenangabe verwendet ist im Prinzip egal.

    Die Diskusion Pascal Strings in den c++ Standard aufzunehmen gab es schon und wurde abgelehnt.

    Einfach im Netz googlen, dann erklärt sich das Problem von selbst.



  • bastl schrieb:

    ...unsinn...

    Nichts für ungut, aber da Du hier derart mit Deiner Unwissenheit glänzt, wäre std::string wirklich die beste Wahl. Das ist am sichersten.
    Und nein, die Größe wird mit allergrößter Wahrscheinlichkeit nicht bei jedem Aufruf von std::string::size() neu berechnet.
    Und mit Pascal-Strings hat das auch nichts zu tun. Das sind in Standardpascal erstmal auch nur char-Arrays fester Länge. Ich schätze mal, Du meinst die Turbopascal Version (und die der Derivate).



  • OK, ich harke da mal ein wenig auseinander:

    bastl schrieb:

    ...
    Ich dachte, daß allseits bekannt ist wie Strings in C, C++ verarbeitet werden....

    Da es in C keine std::string gibt, kann es schonmal nicht gleich sein, wie die beiden Sprachen diese "verarbeiten".

    bastl schrieb:

    ...
    Also C-Strings sind vom typ char abgeleitet ...

    Was Du mit "abgeleitet" meinst, ist mir hier nicht klar, aber es spricht nichts dagegen std::basic_string<my_own_character_type> zu verwenden (außer evtl. unnötiger Mehraufwand) - und dann hat string überhaupt nichts mehr mit char zu tun.

    bastl schrieb:

    ...nur daß <<char str[]>> deutlich mehr Freiheiten hat als std::string (ist eine Klasse)....

    Was soll ein char-Arry an "Freiheiten" mehr haben als std::string? Und was soll das mit der "Klasseneigenschaft" zu tun haben?

    bastl schrieb:

    ...
    (Nachfolgendes ist nicht 100%ig sicher)
    ...

    Das ist nicht nur nicht sicher, sondern sogar ziemlich sicher falsch!
    Zwar gibt der C++-Standard dem StdLib-Entwickler diesbezüglich keine Vorgabe, aber der wäre schon sehr dämlich, wenn er aus

    std::string s1 = s2 + s3;
    

    den o.g. Code machen würde. std::string hat einfach ein Attribut (ist eine "Klasse", wie Du schon zurecht bemerkt hast und als solche kann es jede Menge interne Attribute haben), das die Länge hält und es besteht gar nicht die Notwendigkeit, diese Information irgendwo in den internen Buffer zu "pulen" (weder an den "Anfang" noch implizit via 0-Terminierung).
    Kurz gesagt: Was Du als "tollen Performancetrick" 😉 anpreist (nämlich das "Merken der Längeninfo in einer Variable), macht std::string sowieso schon.

    bastl schrieb:

    ...Ganz im gegensatz zu Pascal Strings wo man selbst dafür sorgen muss mit new das array zu erweitern und die Länge neu eintragen kann, wenn man will, oder entsprechende Member schreibt. ...

    WAS ist "...im Gegensatz zu Pascal Strings ..."?
    Ich vermute, Du sprichst von der std::string-internen Speicherverwaltung. Natürlich kann es sein, dass der eine oder andere Experte in seiner ganz speziellen Anwendug hier und da noch ein wenig optimieren kann - aber in 99,9% der Fälle ist das eher eine theoretische Möglichkeit. Du kannst davon ausgehen, das die StdLib-Etnwickler auch keine Dummköpfe sind ... und letztlich nutzen sie genauso new[]/delete[] wie Du das tätest.
    An einen "Unheimliche Performance"-Vorteil glaube ich da schonmal gar nicht.

    Sagen wir mal so: Selbst ich würde wohl aus dem Stand eine bessere std::string-Implementierung hinbekommen als Du da beschreibst - und ich gehe davon aus, dass die StdLib-Entwickler eher mehr (vermutlich deutlich) Ahnung und Ideen und Zeit dafür haben.
    So ziemlich Nichts von Deinen Mutmaßung über das interne Handling von Strings wird im Standard be- geschweige denn vorschrieben....

    bastl schrieb:

    ...
    Einfach im Netz googlen, dann erklärt sich das Problem von selbst.

    Ich würde eher zu einem guten C++-Buch raten.

    Gruß,

    Simon2.


  • Administrator

    @bastl,
    Es wurde ja schon gesagt, ich will es nur nochmals betonen. Das ist ja absoluter Humbug vom ersten bis zum letzten Wort!

    std::string , wie auch ein C-String , sind nicht von char abgeleitet.

    Ein char[] hat deutlich weniger Freiheiten als ein std::string ! Ein char[] kannst du nicht mal sinnvoll kopieren. Ein std::string kann einfach durch Zuweisung kopiert werden. Du kannst einen std::string auch ganz einfach vergrössern lassen. Und noch vieles mehr, die Liste geht fast ins unendliche, lies doch nur mal die Referenz:
    http://www.cplusplus.com/reference/string/string/

    Zudem ist std::string grundsätzlich ein typedef auf std::basic_string<char, std::char_trais<char>, std::allocator<char> > . Deshalb gibt es ja auch std::wstring . In Zukunft wird es auch noch std::u16string und std::u32string geben.

    Die Länge eines std::string wird nicht immer neu berechnet, sondern sie wird mitgeführt. Nicht ohne Grund verbraucht ein std::string 28 Bytes an Speicher. Er führt nämlich nicht nur die Grösse mit, sondern meistens auch noch einen Capacity-Wert, weil dein std::string wahrscheinlich sinnvollerweise immer ein wenig mehr Speicher allokiert, als er benötigt, so kann er ganz einfach expandieren.

    Allerdings kann ich dir deine Aussage der Neuberechnung auch ganz einfach entkräften. Ein std::string darf mehrere '\0' s enthalten:

    #include <string>
    #include <iostream>
    
    int main()
    {
      std::string str;
    
      str += "hello";
      str += '\0';
      str += " wo";
      str += '\0';
      str += "rld!":
    
      std::cout << str.length() << std::endl;
      // Ausgabe: 14
    
      return 0;
    }
    

    Die Länge eines std::string wird auch nicht im Array gespeichert, sondern eben separat in einer Variable vom Typ std::size_t .

    Anmerkung: Über einen std::string iterieren tut man übrigens oft mit den Iteratoren.

    Und wie war das? C-Strings wurden nicht dazu entwickelt, um auf ihre Elemente in einer For-Schleife zuzugreifen? Klar doch, damit wären alle C-String Funktionen überflüssing:
    http://www.cplusplus.com/reference/clibrary/cstring/

    Aber wahrscheinlich hast du den std::string gemeint und dich nur verschrieben. Mal schauen, std::string ünterstützt das Iteratoren-Konzept und viele von den folgenden Funktionen brauchen For-Schleifen:
    http://www.cplusplus.com/reference/algorithm/

    Allerdings kannst du auch mit einem Index problemlos in einer Schleife darauf zugreifen.

    bastl schrieb:

    Einfach im Netz googlen, dann erklärt sich das Problem von selbst.

    Hast du dir so C++ beigebracht? Dann erstaunt es mich nicht mehr so sehr. Ich empfehle dir dringend, dass du C++ sinnvoll lernst, am besten ein Buch liest. Empfehlungen:
    C++ Primer
    Thinking in C++ 1&2 (auch gratis als PDF erhältlich, nur Englisch)

    Grüssli



  • Beachtet const string und string werden absolut unterschiedlich behandelt!
    Und die Verwendung von size_t bringt schon die dringlichkeit von Pascal Strings zum Ausdruck. Alles strebt förmlich nach Verwendung von Pascal Strings, so auch std::string.
    Da nun alle in C++ im Prinzip Pascal Strings verwenden - wie ich nun mitbekommen habe, stört mich in C++ nur eins:
    Warum kann der Compiler mir die Stringlänge nicht direkt initialisieren?
    Der weiß die doch zur Kompilierungszeit!
    Z.B.: "hallo" ist vom Typ char[6] dann müsste ich doch nicht selbst die Stringlänge bei der Initialisierung einbauen.

    Makro? Definition? irgendwas einfaches, was keine Spuren im Programmkode hinterläßt.

    Muß da noch recherchieren, obs da nicht doch irgendwas giebt.



  • bastl schrieb:

    Beachtet const string und string werden absolut unterschiedlich behandelt!

    const std::string ist konstant. Da es zur Standardbibliothek gehört, sind dem Compiler vielleicht gewisse Optimierungen möglich. Aber mehr nicht, keine Ahnung worauf du abzielst.

    bastl schrieb:

    Alles strebt förmlich nach Verwendung von Pascal Strings, so auch std::string.
    Da nun alle in C++ im Prinzip Pascal Strings verwenden

    Du mit deinen Pascal-Strings... Was gefällt dir an den C++-Strings nicht? Und wieso vergleichst du dauernd mit Pascal?

    bastl schrieb:

    Warum kann der Compiler mir die Stringlänge nicht direkt initialisieren?
    Der weiß die doch zur Kompilierungszeit!

    Nein, in den meisten Fällen nicht. std::string wird normalerweise nicht dazu verwendet, Stringliterale zu speichern, dafür reicht const char* . Und was stellst du dir unter "direkt initialisieren" vor? Dass zur Compilezeit Speicher angefordert wird und sich das zur Laufzeit erübrigt? Ich hoffe nicht.

    bastl schrieb:

    Z.B.: "hallo" ist vom Typ char[6] dann müsste ich doch nicht selbst die Stringlänge bei der Initialisierung einbauen.

    Dann nimm doch eben einen char[6] statt eines std::string s oder char* s... 🙄

    Ich hab ehrlich gesagt keine Ahnung was du überhaupt willst. Die ganze Zeit redest du von irgendwelchen Pascal-Strings und drückst dich unklar aus. Also nochmals: Was ist am Status Quo nicht gut und was hindert dich daran, normale Arrays zu benutzen?



  • Ich dachte, er wollte einfach nur das hier wissen:

    const char[] hallo = "hallo";
    

    ansonsten hf noch hier 😛

    bb

    PS: Der Thread-Titel wird beim schreiben noch immer nicht richtig angezeigt -.-


  • Administrator

    bastl schrieb:

    Beachtet const string und string werden absolut unterschiedlich behandelt!

    Hä? Was willst du uns damit sagen?

    bastl schrieb:

    Und die Verwendung von size_t bringt schon die dringlichkeit von Pascal Strings zum Ausdruck. Alles strebt förmlich nach Verwendung von Pascal Strings, so auch std::string.

    Noch mehr, hä? Ein C String ist bewusst nicht so aufgebaut, wie in Pascal, weil sonst einiges ziemlich seltsam wäre. Mit char Arrays kannst du rohen Speicher verwalten.
    Ein Beispiel aus C:

    char buffer[sizeof(int)];
    int* p = (int*)buffer;
    

    Wie bitte sollte man hier Pascal Strings reinbringen. Absolut unmöglich, da müsste man das Sprachkonzept zuerst verändern. Komm darüber hinweg, dass man es in C nunmal anders löst.

    bastl schrieb:

    Da nun alle in C++ im Prinzip Pascal Strings verwenden ...

    Also das stimmt so nicht, aber von mir aus, wenn du von deinem Pascal nicht loskommen kannst.

    bastl schrieb:

    Z.B.: "hallo" ist vom Typ char[6] ...

    Das ist schonmal insofern falsch, als dass "hallo" den Typ char const[6] hat.

    bastl schrieb:

    ... dann müsste ich doch nicht selbst die Stringlänge bei der Initialisierung einbauen.

    Musst du ja auch nicht. Schau dir nur meine Codes an, welche ich hier schon oft gezeigt habe:

    std::string str = "hello"; // nicht nötig
    char const* p = "hello";   // nicht nötig
    char arr[] = "hello";      // nicht nötig
    

    Grüssli



  • Dravere schrieb:

    Hä? Was willst du uns damit sagen?

    Das geht die was an, die meinen, daß die länge nicht berechnet wird.

    Dravere schrieb:

    Ein Beispiel aus C:

    char buffer[sizeof(int)];
    int* p = (int*)buffer;
    

    Wie bitte sollte man hier Pascal Strings reinbringen. Absolut unmöglich, da müsste man das Sprachkonzept zuerst verändern. Komm darüber hinweg, dass man es in C nunmal anders löst.

    Ich glaube du hast nicht verstanden, was Pascal Strings sind, oder?
    Und was willst du mit diesem eingeschränkten Bsp. überhaupt aussagen?
    Und natürlich bekommt man da einen P-String rein, erst bei sizeof(char) wirds eng!

    Dravere schrieb:

    Musst du ja auch nicht. Schau dir nur meine Codes an, welche ich hier schon oft gezeigt habe:

    std::string str = "hello"; // nicht nötig
    char const* p = "hello";   // nicht nötig
    char arr[] = "hello";      // nicht nötig
    

    Das erste wird intern zu einem abgewandelten P-String.
    Sind leider keine P-Strings!!! - Also Bitte!



  • Du glaubst wirklich, dass im folgenden Code die Länge des Strings mehrmals berechnet wird?

    for( int i=0; i<str.length(); i++)
    

    Das ist falsch. Schau dir doch mal den Code deiner Implementierung an. Das sollte in etwa so aussehen:

    template <...>
    basic_string<...>::length() const
    {
        return m_length;
    }
    

    Da wird nicht nach einem Null-Charakter gesucht oder ähnliches.

    Gruß
    Don06



  • bastl schrieb:

    Das geht die was an, die meinen, daß die länge nicht berechnet wird.

    Bei den meisten std::string -Implementierungen wird sie das auch nicht. Da du das bestimmt wieder besser weisst, will ich dir mal die Standardbibliothek vom MSVC++ zeigen:

    size_type __CLR_OR_THIS_CALL length() const
    		{	// return length of sequence
    		return (_Mysize);
    		}
    
    	size_type __CLR_OR_THIS_CALL size() const
    		{	// return length of sequence
    		return (_Mysize);
    		}
    

    Siehst du? Es wird eine Membervariable zurückgegeben.

    bastl schrieb:

    Ich glaube du hast nicht verstanden, was Pascal Strings sind, oder?

    Da diese Pascal-Strings dermassen wichtig sind und C++ ohne sie folglich abgrundtief schlecht sein muss, könntest du vielleicht mal erklären, wie diese funktionieren. Nicht jeder hat früher mal Pascal programmiert.



  • imho ist unter pascal string einfach nur zu verstehen, dass im ersten zeichen (also index 0) die länge steht - was allerdings zur folge hat, dass das ganze nur bis zu 255 zeichen lang werden konnte - das erkannte man dann iwann als fehler und hatte glaub ich dann ne ganz normale variable für die länge eingeführt...

    aber naja - da c++ keine pascal strings hat, ist es eben einfach doof - und man muss auf zwang versuchen, diese hässlichen gebilde, die imho weit weniger umfangreich als std::string sind, nachzubauen und sich dann wieder beschweren, dass es so schwer ist...

    bb


  • Administrator

    Alles bis auf eines wurde ja schon beantwortet, also lasse ich den Rest weg. Du solltest aber echt einmal sinnvoll C++ lernen, vor allem wenn du so überzeugt von deinen falschen Annahmen bist.

    bastl schrieb:

    Ich glaube du hast nicht verstanden, was Pascal Strings sind, oder?

    Doch, doch. Ein Pascalstring hat an der Stelle 0 die Länge des Strings gespeichert.

    bastl schrieb:

    Und was willst du mit diesem eingeschränkten Bsp. überhaupt aussagen?
    Und natürlich bekommt man da einen P-String rein, erst bei sizeof(char) wirds eng!

    Also ok, vielleicht war auch meine Wortwahl ein wenig schlecht, aber mit dem reinbringen war gemeint, wie man es in die Sprache bringen soll. Aber du hast ja anscheinend auch sonst nicht bemerkt, um was es mir ging.

    Die Sache ist, dass ein Array in C und C++ nichts anderes ist, als eine gewisse Anzahl an Bytes und in diesen Bytes ist nichts anders als die Daten. Der Kompiler tut da überhaupt nichts selber rein.

    Nehmen wir nochmals mein Beispiel:

    // Normal jetzt:
    char buffer[sizeof(int)]; // sizeof(int) gibt meistens 4, also 4 Bytes
    int* p = (int*)buffer;
    p = 0; // ok, alles 4 Bytes sind jetzt 0
    
    // Wenn das Char Array nach Pascal Strings funktionieren würde:
    char buffer[sizeof(int)]; // buffer braucht 5 Bytes, im Byte 0 ist die Grösse des Arrays gespeichert
    int* p = (int*)buffer;
    p = 0; // Die Grösse vom Array ist 0 -> ??? Fehler ...
    

    Ein Pascalstring passt einfach nicht in die Sprache C oder C++ rein, weil er gegen das ganze Speicherverwaltungskonzept verstösst.

    Grüssli



  • bastl schrieb:

    ...

    Dravere schrieb:

    std::string str = "hello"; // nicht nötig
    ...
    

    Das erste wird intern zu einem abgewandelten P-String. ...

    Die Aussage ist einfach falsch: Da wird nichts "...intern zu einem abgewandelten P-String..."
    (es sei denn, du definierst "abgewandelt" als "ersetzt duch std::string")

    Natürlich kannst Du versuchen, die gesamte Welt über P-Strings zu erklären, das bringt aber niemanden weiter - und führt Dich offensichtlich nicht zu einem richtigen Verständnis von std::string.

    Ich kenne das ja auch, dass man sich einer neuen Sprache erst einmal in den Denkmodellen der bisher bekannten nähert, aber irgendwann kommt der Punkt, an dem man "springen" muss; an dem man "Java" programmieren muss und nicht mehr "C++ in Java", "C in C++", "Cobol in Java" ... oder "Pascal in C++".
    Wer nicht "springt", wird nie die Eigenschaften (Vor-/Nachteile) der neuen Sprache wirklich durchschauen.

    Ich würde sagen: Your choice.

    Gruß,

    Simon2.



  • Don06 schrieb:

    Das ist falsch. Schau dir doch mal den Code deiner Implementierung an. Das sollte in etwa so aussehen:

    template <...>
    basic_string<...>::length() const
    {
        return m_length;
    }
    

    Das mit dem berechnen ist nicht mein Problem - jedoch gehe ich nochmal kurz darauf ein.- Es geht nicht darum wann und wo die Länge neu Eingetragen wird sondern darum, daß length() ein Funktionsaufruf ist und nicht ein Zeiger auf diese Variable! - also einige Takte mehr benötigt. - Das hat mich irgendwie gestört - ist aber trivial, gauso wie das Problem, das ich hier lösen wollte!
    Wenn die Länge nicht gespeichert würde, müsste sie jedesmal neu berechnet werden! - würde keiner machen!
    Jedoch ist es zwingend notwendig in C++ diese Variable getrennt vom Array zu halten, da die Aufgabe und Bedeutung der beiden sich total unterscheiden und somit auch deren Aufgaben in der Klasse!
    Man benötigt halt immer eine Klasse, auch wenn man nur eine Funktion damit anstebt.

    Simon2 schrieb:

    Ich kenne das ja auch, dass man sich einer neuen Sprache erst einmal in den Denkmodellen der bisher bekannten nähert, aber irgendwann kommt der Punkt, an dem man "springen" muss; an dem man "Java" programmieren muss und nicht mehr "C++ in Java", "C in C++", "Cobol in Java" ... oder "Pascal in C++".

    Gut erkannt, und immer wieder möchte man mit Hilfe einer anderen Programmiersprache etwas verdeutlichen oder erklären - man läuft immer auf!
    Schlussendlich ist bei effektivster Programmierung der ausführbare Kode im Prinzip bei allen der gleiche.
    Bei mir ist das einzigste Problem, daß QStrings nicht mit std::string harmonieren und ich sowiso eine spezial Suche und Vervollständigung im Umgang mit linuxdateien implementiren möchte. Gibt eine spezial Implementierung, ist aber kein Muss sonder eher aufregend und spannend und bringt hier und da noch ein paar Takte weniger - hab ja sonst nichts besseres zu tun!



  • bastl schrieb:

    Es geht nicht darum wann und wo die Länge neu Eingetragen wird sondern darum, daß length() ein Funktionsaufruf ist und nicht ein Zeiger auf diese Variable! - also einige Takte mehr benötigt.

    Wenn dein Compiler auch nur irgendetwas taugt, kann er den Funktionsaufruf inline erweitern, so daß der Unterschied exakt 0 ist.



  • bastl schrieb:

    ...
    Das mit dem berechnen ist nicht mein Problem ....

    Das war aber bislang das Einzige, worauf Du abzieltest ... der einzige (vermeintliche) Nachteil von std::strings, den Du als Arugment brachtest.

    bastl schrieb:

    ...daß length() ein Funktionsaufruf ist und nicht ein Zeiger auf diese Variable! - also einige Takte mehr benötigt....

    Auch ein Indirektion (wie sie bei Deiner "Zeigervariante" nötig wäre) kostet Zeit - selbst das Auslesen einer Variable kostet Zeit.

    bastl schrieb:

    ... - Das hat mich irgendwie gestört - ...

    Nun gut - wer keine Arbeit hat, macht sich welche 😉
    Natürlich hindert Dch niemand, die Zahl der Funktionsaufrufe zu verringern - allerdings solltest Du bedenken, dass Compiler sowas heutzutage exzellent können (gerade bei simplen Gettern) - Mach doch einfach mal einen Vergkeichstest (im Releasemode compiliert).

    bastl schrieb:

    ...Wenn die Länge nicht gespeichert würde, müsste sie jedesmal neu berechnet werden! - würde keiner machen! ...

    Wie ? Jetzt doch nicht mehr? Hast Du nicht oben erklärt, genau so und nur so würden std::strings funktionieren?

    bastl schrieb:

    ...Jedoch ist es zwingend notwendig in C++ diese Variable getrennt vom Array zu halten, da die Aufgabe und Bedeutung der beiden sich total unterscheiden und somit auch deren Aufgaben in der Klasse!...

    Japp - die Anzahl der Zeichen eines Strings ist eine separate Information und man tut deshalb gut daran, sie separat zu behandeln.
    Was war jetzt Dein Problem dabei?

    bastl schrieb:

    ...Man benötigt halt immer eine Klasse, auch wenn man nur eine Funktion damit anstebt....

    Wer strebt weswegen wofür "nur eine Funktion an"?
    Und was ist falsch daran, eine Klasse zu verwenden?
    Hast Du Berührungsängste mit objektorientierter Programmierung?

    bastl schrieb:

    ...

    Simon2 schrieb:

    Ich kenne das ja auch, dass man sich einer neuen Sprache erst einmal in den Denkmodellen der bisher bekannten nähert, aber irgendwann kommt der Punkt, an dem man "springen" muss; an dem man "Java" programmieren muss und nicht mehr "C++ in Java", "C in C++", "Cobol in Java" ... oder "Pascal in C++".

    Gut erkannt, und immer wieder möchte man mit Hilfe einer anderen Programmiersprache etwas verdeutlichen oder erklären - man läuft immer auf!...

    Dann lass es doch einfach: Ich habe den starken Eindruck, dass niemandem hier die Pascal-Parallele geholfen hat, zu verstehen, was Du sagen willst.
    Warum auch? Hier ist

    • ein C++-Forum,
    • in dem Leute, die C++ kennen
    • sich über C++ unterhalten

    Warum nicht in C++ sagen, was man zu sagen hat?

    bastl schrieb:

    ...Bei mir ist das einzigste Problem, daß QStrings nicht mit std::string harmonieren ...

    Ich kenne mich mit "QStrings" nun leider gar nicht aus. Aber da ich immer noch annehmen muss, dass Du mit std::string nicht allzu viel Erfahrung hast, könnte ich mir vorstellen, dass diese Analyse unzutreffend ist.
    Selbst wenn Du jetzt einen eigenen Stringtypen entwirfst, wirst Du den mit QStrings "harmonisieren" müssen ... und ob das wirklich besser funktioniert als mit std:string?

    bastl schrieb:

    ...und ich sowiso eine spezial Suche und Vervollständigung im Umgang mit linuxdateien implementiren möchte. Gibt eine spezial Implementierung, ist aber kein Muss sonder eher aufregend und spannend und bringt hier und da noch ein paar Takte weniger - hab ja sonst nichts besseres zu tun!

    Ich stimme Dir vollkommen zu: Man kann viel Aufregendes und Spannendes programmieren ... und nicht Alles muss sich wirtschaftlich rechnen.
    Allerdings:
    - "Linuxspezifisches" sehe ich im ganzen Szenario nicht.
    - "Vorzeitige Optimierung" ist in 99% der Fälle vergebliche Liebesmüh: Man hat hinterher einen Haufen Fingerbrecherei gemacht für schlecht wartbaren Code und ein Programm, das langsamer läuft.
    - die Möglichkeiten der StdLib (std::string aber auch viele Andere nützliche Dinge) sind sehr weitgehend ... damit kann man fast alle "spezial Sachen" machen.

    Nochmal mein Tipp: Versuche eine gute Implementierung auf Basis der StdLib hinzubekommen, baue das Ganze dann einmal ohne StdLib und vergleiche:
    - Performance (wie gesagt: Releasemode compiliert)
    - Codelänge
    - Allgemeinverständlichkeit (kannst mal einem Freund den jeweiligen (unkommentierten) Code geben und raten lassen, was er macht)
    - Wartbarkeit (für Erweiterungen, Fehlersuche, ...)
    - Nettoaufwand bei Implementierung und Test.

    DAS wäre doch gleichzeitig spannend als auch lehrreich (egal, welche Variante dann "gewinnt").

    Gruß,

    Simon2.



  • bastl schrieb:

    hab ja sonst nichts besseres zu tun!

    Das Gefühl habe ich auch, wenn ich mir so ansehe, ab welchen Kleinigkeiten (die zum Teil noch falsch sind) du dich aufregst.

    bastl schrieb:

    Jedoch ist es zwingend notwendig in C++ diese Variable getrennt vom Array zu halten, da die Aufgabe und Bedeutung der beiden sich total unterscheiden und somit auch deren Aufgaben in der Klasse!

    Du kannst auch gerne das erste Array-Element zum Speichern der Länge benutzen, wenn du so Freude daran hast. Die Trennung macht schon Sinn, und du hast bisher noch kein Argument dagegen gebracht (nein, weil es in Pascal so ist, ist kein Argument).

    bastl schrieb:

    Man benötigt halt immer eine Klasse, auch wenn man nur eine Funktion damit anstebt.

    So ein Unsinn. Es gibt in C++ nicht umsonst freie Funktionen.

    bastl schrieb:

    Es geht [...] darum, daß length() ein Funktionsaufruf ist und nicht ein Zeiger auf diese Variable! - also einige Takte mehr benötigt. - Das hat mich irgendwie gestört

    Wie gesagt macht das durch Compileroptimierungen keinen Unterschied (selbst wenn es das tun würde, solltest du dich zuerst um wichtigere Dinge kümmern.

    bastl schrieb:

    - ist aber trivial, gauso wie das Problem, das ich hier lösen wollte!

    Hast du dein Problem jetzt gelöst? Falls nicht, würde es vielleicht helfen, es in aller Ruhe nochmals zu formulieren. Vielleicht mehr in die Richtung, was man erreichen möchte und nicht, welcher Teil von C++ einen aufgrund mangelnder Kenntnisse daran hindert.



  • Nexus schrieb:

    Da diese Pascal-Strings dermassen wichtig sind und C++ ohne sie folglich abgrundtief schlecht sein muss, könntest du vielleicht mal erklären, wie diese funktionieren. Nicht jeder hat früher mal Pascal programmiert.

    Klassische Pascal String verwenden ein fixed-size Array (typischerweise 256 Byte gross). Im ersten Byte steht die aktuelle Länge, danach kommt der Text. Nullterminiert sind sie dafür nicht.

    In neueren Pascal-Dialekten werden sie logischerweise nichtmehr verwendet, da 255 als maximale String-Länge einfach nichtmehr ausreicht.

    Und dann gibt es natürlich viele Abarten davon. z.B. Strings die die Länge in zwei oder mehr Byte speichern, die kein fixed-size Array verwenden sondern eins was immer nur so lange ist wie nötig, etc.

    In Windows gibt's auch einen ähnlichen Typ, nämlich BSTR. Ein BSTR ist ein nullterminierter UTF-16 String. BSTR ist ein Typedef auf "wchar_t*", und dieser Zeiger zeigt auf das erste Zeichen des Strings. Das "minus erste" Zeichen gibt die Länge an.

    ----

    Der Vorteil von solchen Strings ist, dass sie unabhängig von der ABI einer bestimmten Programmiersprache sind -- da direkt das Layout im Speicher definiert ist. Dadurch kann man unabhängig von der Sprache Strings herumreichen, hat aber trotzdem den Vorteil, dass man a) die Länge nicht zählen muss und b) Null-Zeichen mitten im String haben kann.
    Der Nachteil ist natürlich dass man sich genau an dieses Layout halten muss, und man dadurch weniger flexibel ist was diverse Optimierungen angeht.

    ----

    Im Prinzip könnte man nach diesem Schema auch std::string implementieren. Macht bloss glaube ich keiner.



  • Der Aufbau einer eigenen Stringklasse ist zumindest sehr lehrreich.
    Lange Zeit bevor STL wirklich Standard war habe ich allen solchen Paketen mißtraut und meine eigene Klasse gebaut, die ich auch debuggen konnte.
    Als Basisklasse sollte man einen ganz simplen char* nehmen, und dann eine Klasse bauen, die dann eben auch herkömmliche C-Strings einfach behandeln kann.
    Klar hätte die eigene Stringklasse den Längenwert bereits intus.
    Dazu muß man aber auch sicherstellen, daß es einfach nicht gelingt, nachträglich ein 0-Zeichen in dem String unterzubringen.
    Für eine solche Operation wäre eine von String abgeleitete Klasse sinnvoll.

    Für weiteres Training programmiere man sich dann mit Templates noch ein Array, damit man dynamisch eine Textdatei einlesen kann und sie direkt in einem Stringarray zur Verfügung steht - wie im guten alten GFA-Basic 🙂

    Wenn ich heute irgendwas mit viel Stringgewurschtel (privat) schnell machen will, pack ich diese Sachen immer noch aus.


Anmelden zum Antworten