Hallo,
ich arbeite gerade an einem relativ umfangreichen (Hobby-)PC-Projekt.
Ich bin in C fit, bin auch beruflich im Embedded-Umfeld unterwegs.
Die objektorientierte Denkweise ist mir auch vertraut, ich hab mit Java
schon mal was mittelgroßes realisiert. Allerdings bin ich kein Fan von
diesem Bytecodezeugs und virtuellen Maschinen, die erst installiert
werden müssen.
Zu Lernzwecken würde ich nun gerne mit C++ arbeiten.
Das ist relativ Neuland für mich.
Aber am PC hab ich ja genug Resourcen, also wieso nicht die
Annehmlichkeiten nutzen, die unter C oft mühselig "per Hand" gelöst
werden müssen?
Nun hab ich aber oft Probleme, die "richtige" Lösung für meine Probleme
zu finden (wobei richtig natürlich Ansichtssache ist).
Wichtig ist mir, das Problem C++-like zu lösen.
Konkretes Beispiel:
Ich lese eine Datei zeilenweise ein, die Datensätze, getrennt durch
Tabulatoren, enthält.
Unter C würde ich nun mit verschiedenen Funktionen auf mein char-array
losgehen, um die Werte aufzudröseln und in Variablen abzulegen. (also so
strtok- und atoi-Geschichten).
Unter C++ sollte das ja wohl einfacher gehen, also mal nach "C++ string
tokenizer" gegoogelt.
Auf
http://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c
werden sehr viele Lösungsvorschläge präsentiert, ich hab mich noch nicht
in alle hineingedacht.
Was mich stört: entweder wird das Problem C-like angegangen
(herumhantieren mit char-arrys und den altbekannten Funktion, mit allen
Vor- und Nachteilen) oder dicke Bibliotheken eingebunden (Boost, Qt).
Funktionieren würde sich vieles, aber mir gehts darum ordentliches C++
zu schreiben, kein Mischmasch und keine Bastellösungen.
Dafür soll mir das Projekt ja dienen...
Was macht ihr denn in so einer Situation?
Bibliotheken einbinden ohne Ende?
Selber Work-arounds und Wrapper schreiben?
C-style programmieren?
Mit diesem C++ hab ich irgendwie noch so meine Probleme, wahrscheinlich
weil einfach so viele Lösungen angeboten werden...
Viele Grüße,
masl
Geht es dir um das lernen von C++ oder um eine Probelmlösung?
Ich würde verschiedene Ansätze austesten.
1. Jedes C(ANSI.89) Programm ist ein C++ Programm, aber nicht umgekehrt.
Also C-Style schreiben und gucken...
2. UML-Designer verwenden und C++ Template erzeugen und ausfüllen
oder 3. Bücher / E-Books besorgen und lesen, lesen, lesen...
Gruß aus Berlin
Seh hier kein Problem. Schreib dir eine Klasse die strtok- und
atoi-Geschichten ausführt und dann haste dein C++.
Oder benutz die tausend anderen Möglichkeiten. Ein richtig Richtig gibt
es hier wohl nicht...
Rene Schube schrieb:> Geht es dir um das lernen von C++ oder um eine Probelmlösung?
Schwer zu sagen, um was es mir genau geht.
Ein wirkliches Problem das ich lösen muss hab ich nicht. Ich hab mir ein
Projekt ausgedacht um mal was mit C++ zu machen.
C++ lernen: Jein. Ich kann C++, im Sinne von "Ich kenne die Syntax. Ich
bin mit der objektorientierten herngehensweise vertraut. Ich weis wie
Vererbung und Polymorphie funktionieren. Ich weiß was ein
Konstruktor/Dekonstruktor macht. Ich kenne Überladung von Operanden und
Funktionen.".
Was mir fehlt ist der gute C++-Stil. Man kann die Probleme auf so
vielfältige Weise lösen, dass ich als Anfänger erstmal erschlagen bin.
Man kann fast alles erstmal "oldschool" lösen. Das will ich nicht, für
das brauch ich kein C++. Ich, mit meinem C-Hintergrund, habs da echt
schwer nicht in die alten Verhaltensmustern zurückzufallen.
Es gibt für jedes Trivialproblem zig Bibliotheken, das hab ich gerade an
meinem Beispiel mit der String-Zerlegung gesehen.
Ich halte es aber für nicht elegant und unüberschaubar, zig Bibliotheken
für jeden Furz einzubinden.
Die STL wär mir erstmal am Liebsten. Leider dachte ich (mit meinem
C-Hintergrund) bisher, die STL wäre die Eierlegende Wollmilchsau, was
sie aber leider nicht ist. Also bleibt wieder nur, diese
Unzulänglichkeiten zu umschiffen ("Bastellösungen") wie in C bisher
notwendig war, oder wieder auf andere Bibliotheken auszuweichen.
Mir fehlt da einfach die Praxis...
Na dann würde ich aus meinen Ansätzen den 2. versuchen.
UML-Designer -> Code-Templates ...
Je nach dem Designer erhält man eine vernünftige Struktur und im Prinzip
ein lauffähiges Programm-Gerüst.
-> http://de.wikipedia.org/wiki/UML-Werkzeug#Codeerzeugung
Die grosse Suchmaschine findest auch reichlich Infos: "UML-Designer C++"
Wenn die Grundlagen sitzten ist es, denke ich der einfachste Weg.
masl schrieb:> Die STL wär mir erstmal am Liebsten.
Na, dann machs halt mit der STL.
Du hast eine wunderbare std::string Klasse.
Sieh dir an, welche Member die hat und such dir einen Weg, wie du mit
den vorhandenen Funktionen deine gewünschte Funktionalität
zurechtpfriemeln kannst.
Entweder du willst fertige Tokenizer. Dann musst du zu den großen
Bibliotheken gehen. Oder du nimmst eine Nummer kleiner und setzt dir mit
wenig Aufwand aus den Primtiv-Basisklassen das gewünschte zusammen.
Einen String an Tabulatoren in Einzelteile aufzubrechen ist ja jetzt
nicht wirklich Raketentechnik, wenn man Funktionen wie find, erase,
substr zur Verfügung hat. Die Eregebnisse könnte man zb in einen
vector<string> stecken und die Sache ist gegessen.
> Unzulänglichkeiten zu umschiffen ("Bastellösungen") wie in C bisher> notwendig war,
Ne, ne.
Langsam.
Alleine dadurch, dass dir die std::string schon mal das ganze dynamische
Memory Management abnimmt, sparst du dir gegenüber einer reinen C-Lösung
schon mal 80% vom Code und 95% aller dabei möglichen Fehler. Und der
Rest ist eine Kombination aus ein paar Member Funktionen von std::string
uns std::vector mit einer Schleife drumherum. Also soooo wild ist das
auch wieder nicht. STL bedeutet ja nicht, dass es für jeden erdenklichen
Aufgabenfall eine fix&fertige Lösung gibt.
Vlad Tepesch schrieb:> Da ist es ziemlich straight forward.
ja und leider nicht so schnell wie jeden billige C version.
> QStringList fields = line.split("\t");
hier wird eine array angelegt wo der gleiche Inhalt wie im String drin
steht.
Man kopiert also alle daten und braucht extra nach eine
verwaltungsstrukur.
In C geht man einfach auf dem String durch und nimmt die elemente die
man braucht.
Mir ist klar das es auf einem normales PC kein unterschied merkbar ist,
aber mir stört so eine Resourcenverschwendung. Somal das ganze in C
nicht (viel) mehr code ist.
Peter II schrieb:> Vlad Tepesch schrieb:>> Da ist es ziemlich straight forward.>> ja und leider nicht so schnell wie jeden billige C version.
Solange die Strings von einem File kommen, ist das piep schnurz egal.
Ob die Zerlegung 50 oder 150 Nanosekunden dauert, interessiert
heutzutage industriell keinen mehr. Wichtiger ist, dass es fehlerfrei
und schnell programmiert werden kann.
Peter II schrieb:> In C geht man einfach auf dem String durch und nimmt die elemente die> man braucht.
klar geht das effizienter und Ressourcensparender.
Das mag sogar wichtig sein, wenn man riesige Datein einliest.
Großer Vorteil ist jedoch (gerade für Programmieranfänger), dass man
recht wenig falsch machen kann, da sich die Klassen um die
Speicherverwaltung kümmern.
Die Wahrscheinlichkeit sich irgendwo was durch Buffer-Overruns
kaputtzuschreiben geht gegen 0.
Karl Heinz Buchegger schrieb:> Solange die Strings von einem File kommen, ist das piep schnurz egal.> Ob die Zerlegung 50 oder 150 Nanosekunden dauert, interessiert> heutzutage industriell keinen mehr. Wichtiger ist, dass es fehlerfrei> und schnell programmiert werden kann.
Filesystem können auch daten mit 500Mbyte/s liefern, dann hat die CPU
schon zu tun.
Wenn ich mit den gleichen Aufwand es schneller programmieren kann, warum
sollte ich denn resourcen verschwenden nur weil es gerade modern ist?
Vlad Tepesch schrieb:> Großer Vorteil ist jedoch (gerade für Programmieranfänger), dass man> recht wenig falsch machen kann, da sich die Klassen um die> Speicherverwaltung kümmern.> Die Wahrscheinlichkeit sich irgendwo was durch Buffer-Overruns> kaputtzuschreiben geht gegen 0.
er ist aber kein Programmieranfänger, er möchte nur wissen wie man es in
C++ machen würde. Und hier sehen ich keine sinnvolle verwendung für C++
und würde es genauso wie in C machen.
Peter II schrieb:> Wenn ich mit den gleichen Aufwand es schneller programmieren kann, warum> sollte ich denn resourcen verschwenden nur weil es gerade modern ist?
:-)
Das haben wir alles in den letzten 40 Jahren gesehen. Die Anzahl der
Programmabstürze, fehlerhaften Daten, Möglichkeiten zur Manipulation ist
legendär. Aber die Hauptsache man hat es schnell und resourcenschonend
geschrieben :-)
Hautzutage hat sich Gott sei Dank der Fokus verschoben. 'Speed um jeden
Preis' ist heute kein Thema mehr.
> Wenn ich mit den gleichen Aufwand
Genau da liegt der Trugschluss. Bis du in deinem C tatsächlich 'das
gleiche Resultat hast', ist dein persönlicher Aufwand in C beträchtlich
höher! Es reicht nicht, wenn das C-Programm ungefähr dasselbe macht, wie
das C++ Programm. Es muss sich auch in Fehlersituationen gleichwertig
Verhalten (nämlich den Fehler abfangen und etwas sinnvolles damit tun).
Und dann wird deine 'schnell-schnell' Lösung dann nämlich plötzlich gar
nicht mehr so 'schnell-schnell'.
Und das fängt schon mit dieser ganz banalen Zeile an
1
QStringline=input.readLine();
bis du DAS in C #gleichwertig# hast, hab ich meine C++ Lösung schon
ausgeliefert :-)
(Das geht nicht gegen dich persönlich.)
Karl Heinz Buchegger schrieb:> Und das fängt schon mit dieser ganz banalen Zeile an> QString line = input.readLine();> bis du DAS in C 'gleichwertig' hast, hab ich meine C++ Lösung schon> ausgeliefert :-)
gegen die zeile habe ich auch nichts - die Trick besteht ja daran immer
das zu verwenden was jeweil sinnvoll ist.
Es ging mir nicht um das einlesen der Zeile sondern um das Parsen und da
bin ich mit C genauso schnell.
Peter II schrieb:> Karl Heinz Buchegger schrieb:>> Und das fängt schon mit dieser ganz banalen Zeile an>> QString line = input.readLine();>> bis du DAS in C 'gleichwertig' hast, hab ich meine C++ Lösung schon>> ausgeliefert :-)>> gegen die zeile habe ich auch nichts - die Trick besteht ja daran immer> das zu verwenden was jeweil sinnvoll ist.>> Es ging mir nicht um das einlesen der Zeile sondern um das Parsen und da> bin ich mit C genauso schnell.
Es spricht ja auch nichts dagegen, auch in C++ dieses Parsen auf einem
std::string zu machen und sich die gefundenen Positionen in einem size_t
Array zu merken. Die Möglichkeiten sind ja da.
Wenn es dir aber eben nicht reicht, das Parsen quasi 'in place' im
String zu machen, sondern wenn du die Strings dann tatsächlich einzeln
benötigst, dann bietet dir C++ auch dann Möglichkeiten, welche du in C
so erst mal nicht hast.
Gerade dann, wenn es eben darum geht, mal schnell eben ein Werkzeug zu
schreiben, welches ein gerade anfallendes Problem kurzfristig löst, ist
man mit einem objektorientierten Ansatz meistens um einiges schneller,
eben weil man sich nicht um die kleinen Stolpersteine kümmern muss.
Karl Heinz Buchegger schrieb:> Hautzutage hat sich Gott sei Dank der Fokus verschoben. 'Speed um jeden> Preis' ist heute kein Thema mehr.
Unterschreibe ich zu 100%. Obwohl es immer sinnvoll ist im Hinterkopf zu
wissen wie günstig/ungünstig bzgl. Laufzeit eine Lösung ist. Zumindest
tendenziell.
In größeren Softwareprojekten sind üblicherweise <1% des Codes
Zeitrelevant.
Die Kunst ist es nicht Code zu optimieren, bei dem es sch--- egal ist ob
er in einer oder 10 µs ausgeführt wird, weil der User doch eine Sekunde
braucht, sondern genau dieses 1% zu optimieren.
Karl Heinz Buchegger schrieb:> Es spricht ja auch nichts dagegen, auch in C++ dieses Parsen auf einem> std::string zu machen und sich die gefundenen Positionen in einem size_t> Array zu merken. Die Möglichkeiten sind ja da.
richtig, mich hat nur das split mit dem ereugen das Array gestört. Klar
kann man auch mit einem iterator über einen std:string gehen dagen ist
auch nichts zu sagen.
Man sollte nur halt wissen was alles bei so einem einfach split
passiert.
Hui, da hab ich ja was losgetreten :-)
Wenn mein Programm ein wenig langsamer läuft als ein reines C-Pendant
dann kann ich damit leben.
Wie schon öfter erwähnt, wir sind a) auf einem modernen PC unterwegs
und b) haben wir (ich) nichts zeitkritisches zu Lösen. Hier wird eine
Datei beim Programmstart eingelesen und geparsed.
Deswegen lege ich Wert darauf dass der Code möglichst leicht zu lesen
ist (und damit leichter zu warten) und dass das Programm zuverlässiger
(==weniger Fehleranfällig) wird.
Sonst könnt ich ja gleich bei C bleiben.
Trotzdem will ich natürlich nicht immer sofort den Holzhammer
herausholen der alles passend macht wenns auch ein einfacheres Werkzeug
tut.
Und dieses Wissen, wann welche Vorgehensweise angebracht ist, fehlt mir
eben.
C++ bietet da eben ein weites Spektrum an Werkzeug"größen". Ich kann ein
Problem sehr abstrakt angehen indem ich Klassen benutze die ihrerseits
dutzende Klassen und Methoden kapseln und mir großen Komfort
ermöglichen.
Ich kann aber auch direkt an den einzelnen Bits meiner Daten
rumpfriemeln, wenn ich wollte, und alles "zu Fuss" machen.
Ich denke mal, es verlangt einiges an Übung und Erfahrung, das passende
Werkzeug auszuwählen.
Ich habe hier auf einige interessante Meinungen gehofft, und diese auch
erhalten.
Ich bin dann mal weiterüben :-) (erstmal nur mit STL)
Peter II schrieb:> Filesystem können auch daten mit 500Mbyte/s liefern, dann hat die CPU> schon zu tun.
schon, aber 99% der zeit wirst du die felder (strings) in andere typen
umwandeln und nicht zeichen herumschieben.
daher ist der split vollkommen egal!
außerdem wirst du mit den eingaben auch was anderes machen als sie bloß
umzuformatieren... sonst würde ich stark zur verwendung von awk raten :)
73
Hans schrieb:> schon, aber 99% der zeit wirst du die felder (strings) in andere typen> umwandeln und nicht zeichen herumschieben.>> daher ist der split vollkommen egal!
kleinvieh mauch auch mist!
> außerdem wirst du mit den eingaben auch was anderes machen als sie bloß> umzuformatieren... sonst würde ich stark zur verwendung von awk raten :)
wenn es nicht schnell sein muss nehme ich auch kein C/C++ mehr dann ist
c# dran.
> Hautzutage hat sich Gott sei Dank der Fokus verschoben. 'Speed um> jeden Preis' ist heute kein Thema mehr.
Stimmt, heute gibt es schon Leute die laden ihr Handy taeglich auf und
halten das fuer normal. Ich erlaube mir aber das fuer peinlich zu
halten.
Olaf
Olaf schrieb:>> Hautzutage hat sich Gott sei Dank der Fokus verschoben. 'Speed um>> jeden Preis' ist heute kein Thema mehr.>> Stimmt, heute gibt es schon Leute die laden ihr Handy taeglich auf und> halten das fuer normal. Ich erlaube mir aber das fuer peinlich zu> halten.
Was hat das eine mit dem anderen zu tun?
Ob sich ein Dialog in 1 Millisekunde oder in 1.5 Millisekunden
schliesst, interessiert keine Sau. Beides ist für einen Benutzer "nicht
merkbar".
Karl Heinz Buchegger schrieb:> Ob sich ein Dialog in 1 Millisekunde oder in 1.5 Millisekunden> schliesst, interessiert keine Sau. Beides ist für einen Benutzer "nicht> merkbar".
wenn die software 1Mil nutzer die damit einen höheren Stromverbrauch in
diese zeit haben könnte man schon fast eine Windrad sparen.
Peter II schrieb:> Karl Heinz Buchegger schrieb:>> Ob sich ein Dialog in 1 Millisekunde oder in 1.5 Millisekunden>> schliesst, interessiert keine Sau. Beides ist für einen Benutzer "nicht>> merkbar".>> wenn die software 1Mil nutzer die damit einen höheren Stromverbrauch in> diese zeit haben könnte man schon fast eine Windrad sparen.
Ach komm, das kannst du garnicht ernst meinen.
Der PC läuft bei den meißten eh einfach so zur Gaudi, weil keiner Lust
auf runterfahrn und neu starten hat.
Keiner sagt hier dass man alles dreckig und ressourcenfressend
programmieren muss.
Ihr tut ja alle als würde die Benutzung einer Bibliothek einen Overhead
ohne Ende darstellen.
Aber wisst ihr was?
Genau so wie ihr niemals mit Assembler den C-Compiler in Sachen
Optimierung schlagen werdet (jaja, zu 95% nicht) so werdet ihr mit
Bytegepfriemel und LowLevel-Zugriffen wie in C üblich nicht die
Performance der STL nachbilden können, zumindest nicht mit annähernd
diesem Komfort und der Fehlertoleranz.
Denn, tut mir leid, den Leuten die solche Libs schreiben trau ich mehr
zu als dem durchschnittlichen Forumuser.
Wieso also sich nicht auf Lösungen verlassen, die sich weltweit
millionenfach bewährt haben?
le x. schrieb:> Wieso also sich nicht auf Lösungen verlassen, die sich weltweit> millionenfach bewährt haben?
Na weil "ein Programm erst dann perfekt ist wenn man nichts mehr
weglassen kann ohne die Funktion zu beeinträchtigen (tm)" ;)
Zumindest verkündet das ein einst berühmter Geist aus der technischen
Prähistorie in latent aggressivem Ton regelmäßig :)