String wiedergeben
-
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.
-
RussianTux schrieb:
Wozu brauche ich die std::string lib? Ich sehe keinen einzigen Grund dafür
Vorteile:
- Die Klasse hat sehr sicher keine Speicherlecks oder sonstige Scherze.
- Die Klasse ist sehr sicher performanter als Deine.
- Die Klasse ist bekannt und weitläufig genutzt, deine Algorithmen integrieren sich also besser in bestehende Projekte.Nachteile:

-
otze schrieb:
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.
1. Meine Funktionen sind ebenfalls getestet und brauchen nur ein Klassen-Overlay
das wars, WOZU std::string блеать ?! 
2. Meine Splitfunktion ist auf reiner C/C++ Syntax geschrieben und funktioniert ohne jegliche Bibliotheken, 99% frei von allem...
-

-
Beantworte mal meine Frage. std::string hat viele Vorteile und keine Nachteile. Erinnert mich an bisschen an die GoingNative Frage an Sutter, da hat auch jemand erzählt, wie seine Arbeitskollegen die Standardbibliothek als irgendetwas externes sehen und sie nicht benutzen wollen. (Gab viel Gelächter danach.) Also los, bau dir eine eigene Stringklasse, aber finde dich damit ab das Gespött der std::string-Kenner zu sein. (Und das sind viele.)
-
RussianTux schrieb:
1. Meine Funktionen sind ebenfalls getestet und brauchen nur ein Klassen-Overlay

Mal ganz davon abgesehen, dass ich nicht sehe, wieso man noch Memberfunktionen braucht, wenn es das Ganze schon als freie Funktionen gibt, kannst du bitte mal zwei, drei Algorithmen posten?
-
Michael E. schrieb:
RussianTux schrieb:
1. Meine Funktionen sind ebenfalls getestet und brauchen nur ein Klassen-Overlay

Mal ganz davon abgesehen, dass ich nicht sehe, wieso man noch Memberfunktionen braucht, wenn es das Ganze schon als freie Funktionen gibt, kannst du bitte mal zwei, drei Algorithmen posten?
Ohne Klassen-Overlay:
const char* string1 = "text1", string2 = "TEXT2"; //eine der einfachsten algorithmen... string1 = s_convert_toUpper(string1); string2 = s_convert_toLower(string2); cout << string1 << "\n"; cout << string2 << "\n";Mit Klassen-Overlay
String string1 = "text1", string2 = "text2"; string1.convert_toUpper(); string2.convert_toLower(); cout << string1 << "\n"; cout << string2 << "\n";Beides funktioniert, aber das 2te ist etwas geordneter
-
Geschmackssache. Aber kannst du bitte noch zwei nicht triviale Algorithmen posten? Danke.
-
Das ist ja noch schlimmer als bei std::string, und da sind die Memberfunktionen schon nicht mehr das Wahre.
@TE Google mal nach "prefer non-member non-friend functions". Da gibt es zwar noch Spielräume (meiner Meinung nach), aber solche Dinge sollten definitiv freie Funktionen sein.
-
Der Vorteil kehrt sich um, sobald du den String selbst nicht verändern willst und das Resultat daher in einem anderen Ziel speichern musst.
Wie sieht denn dein convert_toUpper aus? Meins funktioniert ungefähr so:
void convert_toUpper(std::string& str){ std::transform(str.begin(),str.end(),str.begin(),std::toupper); }//edit oder für wide character unterstützung:
template<class CharT, class Alloc> void convert_toUpper(std::basic_string<CharT,Alloc>& str){ typedef std::basic_string<CharT,Alloc> String; String::iterator end = str.end(); std::locale loc; for(String::iterator pos = str.begin(); pos != end; ++pos){ *pos=std::toupper(*pos,loc); } }
-
Michael E. schrieb:
Geschmackssache. Aber kannst du bitte noch zwei nicht triviale Algorithmen posten? Danke.
Ausnahme mäßig ja, zwei vergleichsweise kleinen Algorithmen s_convert_toUpper & s_get_lenght:
const char* s_convert_toUpper(const char* string) { if(string[0] == '\0') return ""; const char* buffer_out; unsigned int buffer_size = S_BUFFER_STARTSIZE; char* buffer = new char[buffer_size]; unsigned int pos_str; for(pos_str = 0; string[pos_str] != '\0'; pos_str++) { if(pos_str > buffer_size) { buffer_size *= 2; char* buffer_sec = buffer; buffer = new char[buffer_size]; unsigned int pos_b = 0, pos_bs = 0; for(pos_b = 0, pos_bs = 0; buffer_sec[pos_bs] != '\0'; pos_b++, pos_bs++) { buffer[pos_b] = buffer_sec[pos_bs]; } buffer[pos_b] = '\0'; } //if character is a small one if(string[pos_str] <= 122 && string[pos_str] >= 97) buffer[pos_str] = (string[pos_str] - 32); else buffer[pos_str] = string[pos_str]; } buffer[pos_str] = '\0'; buffer_out = buffer; return buffer_out; }unsigned int s_get_lenght(const char* string) { unsigned int count; for(count = 0; string[count] != '\0'; count++); return count; }Nahezu alle Algorithmen funktionieren durch Iteration, man geht Stück für Stück durch die Zeile...
Mehr werde ich leider nicht veröffentlichen dürfen...
-
WTF machst du da?
void to_lower(std::string& s) { std::transform(s.begin(), s.end(), s.begin(), std::tolower); }
-
Das habe ich mir schon fast gedacht. Soviel zum Thema "getestet".
const char* s_convert_toUpper(const char* string) { if(string[0] == '\0') return "";Hier gibst du einen Pointer auf "" zurück, im Normalfall aber mit new angelegten Speicher. Soll der Aufrufer nun den Rückgabewert deleten oder nicht?
const char* buffer_out; unsigned int buffer_size = S_BUFFER_STARTSIZE; char* buffer = new char[buffer_size]; unsigned int pos_str; for(pos_str = 0; string[pos_str] != '\0'; pos_str++) { if(pos_str > buffer_size)Falsche Bedingung. Bereits für pos_str == buffer_size musst du das Array vergrößern.
{ buffer_size *= 2; char* buffer_sec = buffer; buffer = new char[buffer_size]; unsigned int pos_b = 0, pos_bs = 0; for(pos_b = 0, pos_bs = 0; buffer_sec[pos_bs] != '\0'; pos_b++, pos_bs++) { buffer[pos_b] = buffer_sec[pos_bs]; }Da du buffer_sec nicht nullterminiert hast, funktioniert dieses Kopieren (warum benutzt du eigentlich nicht eine Kopiermethode aus der Standardbibliothek wie memcpy?) nicht. Außerdem deletest du das alte Array nicht, sodass du ein Speicherleck hast.
Immer noch sicher, dass du nicht std::string benutzen möchtest, wo die Funktion ein Einzeiler ist?
-
RussianTux schrieb:
Nahezu alle Algorithmen funktionieren durch Iteration, man geht Stück für Stück durch die Zeile...
Und was genau ist an dem Scheiß jetzt besser als richtiges C++?
RussianTux schrieb:
Mehr werde ich leider nicht veröffentlichen dürfen...
Finde ich auch.
Michael E. schrieb:
Das habe ich mir schon fast gedacht. Soviel zum Thema "getestet".
const char* s_convert_toUpper(const char* string) { if(string[0] == '\0') return "";Hier gibst du einen Pointer auf "" zurück, im Normalfall aber mit new angelegten Speicher. Soll der Aufrufer nun den Rückgabewert deleten oder nicht?
Die naheliegende Lösung: Nie irgendwas freigeben

Ist sogar total effizient, man spart ja die ganzenfree-Aufrufe.
Alle modernen Sprachen haben einen GC, also sollte das kein Problem sein.