Geht das eleganter?
-
edit: Nö, ist mir doch zu doof, sowas von undankbar.
-
SucherDerEleganz schrieb:
Deine plumpen Provokationen kannst du dir übrigens sparen.
Du solltest nicht gleich alles als Provokation auffassen. Es ist in der Tat so, dass das Verständnis von "einfach" subjektiv ist und davon abhängt, wie schwierig der Programmierer es empfindet, etwas umzusetzen.
SucherDerEleganz schrieb:
Ja, ich habe noch nicht viel mit Templates gemacht, aber mit C++ kenne ich mich doch einigermaßen aus.
Templates sind aber gerade ein sehr mächtiges Instrument von C++. Und nur weil du sie nicht kennst, musst du sie nicht als schlechte Lösung darstellen.
SucherDerEleganz schrieb:
Es ist effizient, weil es ohne Schnörkel ist. Keine Funktionsaufrufe, keine Polymorphie usw. Einfach ein roher Speicherbereich.
Es ist nicht unbedingt schneller, nur weil es C ist. Eine höhere Abstraktionsebene impliziert keine Verlangsamung des Codes. Von "effizient" würde ich an der Stelle sowieso nicht sprechen, da C++-Mittel meistens effizienter sind (mit weniger Aufwand erreicht man mehr). Abgesehen davon erreicht man durch den eventuellen Geschwindigkeitsvorteil unsicheren und fehleranfälligen Code, was die Bilanz fragwürdig macht...
SucherDerEleganz schrieb:
Wo ist beispielhafter Code etc.?
[...]
Eine Lösung ist sowas wie: Du könntest ein tr1::array nehmen und dann folgendes machen: <Code>
Sowas gab es hier nie. Nur das blöde "zu ungenaue Beschreibung", da kann man nicht konkret helfen. lol..
[...]
Aber da keine KONKRETEN Vorschläge kamen (CODE!), lass ich es einfach beim void*.
[...]
(PS: Auch interessant, anstatt konkrete Vorschläge zu machen kommt nur Meta Gelaber und plumpe Provokationen von dir Simon2
)Ich denke, das hast du nun genug häufig erwähnt. Sag mir bitte, wieso du einfach nicht in der Lage bist, wenigstens zu versuchen, die genannten Möglichkeiten selbstständig umzusetzen. Wenn du sie nicht kennst, kannst du ja recherchieren, z.B. auf www.cplusplus.com. Wenn du dann konkrete Fragen hast, kannst du immer noch fragen. Aber einfach stur darauf zu beharren, dass dir Code-Beispiele gebracht werden, bringt dich nicht wirklich weiter. Eine gewisse Selbstständigkeit sollte man als Programmierer schon besitzen.
-
SucherDerEleganz schrieb:
...Das man den Code eben beim 1. Blick durchschaut. ...
Und das Kriterium soll NICHT vom Wissenstand des Betrachter abhängen ?

Ich kann Deinen Code (oder den der Anderen hier) ja mal meinen 10jährigen Töchtern vorlegen....
Genau DAS habe ich behauptet (dass es von Wissenstand des Betrachters abhängt) - das hatte nichts mit einer Provokation zu tun.
Ich habe nicht einmal behauptet, dass Dein Code NICHT einfach sei - nur, dass "einfach" und "effizient" nicht viel mit "sauber" zu tun haben.SucherDerEleganz schrieb:
...Es ist effizient, weil es ohne Schnörkel ist. Keine Funktionsaufrufe, keine Polymorphie usw. Einfach ein roher Speicherbereich....
Da hast Du aber eine sehr eigene Definition von "effizient". Ich kenne nur die Definition "mit denkbar wenig Einsatz (üblicherweise Speicher und Rechenleistung aber seit einigen Jahren oft auch Entwicklungszeit) zum Ziel". Und das hängt sehr stark von der Aufgabe und dem Rechnerumfeld ab. Das allozieren eines Speicherbereichs zur Laufzeit kann durchaus ineffizienter sein als andere Techniken (z.B. die Stackspeicher verwenden). Auch Polymorphie ist in vielen Fällen nicht ineffizient (und schon gar nicht ineffizienter als wenn man sie selbst mittels if/else nachzubilden versucht).
SucherDerEleganz schrieb:
...sagt ja einiges über deinen Charakter aus...
Aha - Psychologieausbildung abgeschlossen ? (DAS war jetzt eine Provokation :p ;))
Über Charakter und Motivationen sollte man nach meiner Erfahrung bei solchen flüchtigen Internetkontakten besser nicht spekulieren. Ich lasse das auch.SucherDerEleganz schrieb:
...Man kann keine Vorteile von Lösungen sehen, wenn keine genannten wurden. ...
Hmmm - 3. Post (insgesamt die 2. Antwort) enthält bereits einen Vorschlag. 3 Posts weiter wirst Du auf tr::array und std::vector verwiesen, die sich nahezu identisch zu Arrays verwenden lassen - und üblicherweise sogar Arrays einsetzen, so dass sogar der Effizienzaspekt abgedeckt ist. Irgendwie sind hier bei dem von Dir an den Tag gelegten Selbstbewusstsein Alle davon ausgegangen, dass Du mit den Standarddokus und -Beispielen klarkommst.
Du hast übrigens selbst auch nicht gerade besonders viel Code beigesteuert. So ist mir z.B. anhand Deines Codes nicht klar, warum Du überhaupt zwischen diesen verschiedenen Typen unterscheiden musst - und wie "unterschiedlich" Du die verschiedenen Datentypen überhaupt behandeln musst.SucherDerEleganz schrieb:
...Dass es in C++ (!) eleganter ginge mag sein, drum bin ich ja hier. ...
Merkt man aber nicht. So richtig strahlst Du "Annahmebereitschaft" nicht gerade aus.
Aber nun gut. Den templates-Ansatz mal etwas näher an Deinen Fall angepasst:
template <typename> void methode1(vector<T> const& v) ... y = v[index] * scaleY; // keine Fallunterscheidung mehr möglich ... } template <typename T> void fachlichkeit(size_t) { vector<T> v(size); methode1(v); ... } int main() { ... switch(dataType) { case TYPE_BYTE: fachlichkeit<char>(X); break case TYPE_FLOAT: fachlichkeit<float>(X); break ...Wenn für bestimmten Typen fachlichkeit() oder methode1() anders aussehen müssen, kannst Du Spezialisierung nutzen:
template <> void methode1(vector<mySpecialClass> const& v) and_now_for_something_completely_different(v[3]); }Gruß,
Simon2.
-
Badestrand schrieb:
SucherDerEleganz schrieb:
@Badestrand: Wenn ich ein double array chars einlese, wie komme ich denn dann bitte an den 3. char ran?
Mit dem dritten Element vom Array, also
arr[2]. Und das funktioniert eben, weil in dem double-Array nur doubles drin sind, welche rein kommen, indem du die Bytes aus der Datei in doubles umwandelst.Sorry, aber was du da sagst ist einfach falsch. Wenn ich in einem double array arr[2] mache, dann liefert er mir sizeof(double) bytes ab Speicherstelle arr+sizeof(double) und da sizeof(double) nun mal größer als 1 ist (meistens wohl 8), ist 1 Element 8 Byte breit. Auf die einzelnen chars kann ich NICHT zugreifen! Außerdem liefert mir arr[2] einen double, sprich das Bitmuster der chars, oder shorts oder was auch immer wird völlig anders interpretiert. Ansonsten möcht ich dazu nicht mehr eingehen, der Vorschlag ist einfach nur lächerlich;)
@Simon2: Was soll f.[index] bedeuten? Vermutlich meinst du v[index], oder?
Naja, den Code finde ich nicht wirklich so gut. Erstens habe ich ja doch wieder eine Fallunterscheidung drinnen (switch), die ich ja umgehen wollte. Außerdem ist das bei mir so auch nicht verwendbar. Ich brauche ja einen Container/Array als Member, das mir die Daten aus der Datei hält (also ein Pendant zu void* foo). Wie soll das bei deinem Code gehen? Bei Templates muss der Typ ja zur Compilezeit feststehen, es ginge also nur ein tr1::array<int> oder was auch immer, aber das funktioniert nicht. Und ein array<T> könnte ich nur machen, wenn die Klasse eine Template-Klasse ist, was auch wiederrum schlecht ist.Und um 2 (!) Zeilen Code, die mir nicht so gefallen (die 2 Downcasts beim Zugriff aufs void* array), zu verbessern möchte ich nicht wirklich ein Factory Pattern oder sowas programmieren;)
Hätte ja sein können, dass es da irgend nen Trick gibt mit ner Struktur oder typeof oder sonst was. Aber wenn es da keine wirklich simple Alternative gibt (wenig Code), dann lass ich einfach so wie es jetzt ist.
-
@SucheDerEleganz: Der Vorschlag ist nicht lächerlich, du verstehst nur nicht genau, was ich meine
Also ich schlage dir nicht vor, die Bytes einfach roh in den double-Speicher reinzukopieren, denn das wäre total dämlich wie du ja selbst sagst.
Ich schlage stattdessen vor, jeden Zahlenwert in einem double-Wert zu speichern, egal ob es vorher ein char, int oder float war.
Um es wirklich deutlich zu machen (sonst geht das noch 10 mal hin und her): Bei einer Byte-Datei liest du das erste Byte der Datei ein, wandelst dieses Byte in ein double um (der dann logischerweise einen Wert zwischen 0..255 enthält) und pusht diesen double in das Array rein. So hast du dann kein Array aus Bytes/Shorts/.., sondern ein Array aus doubles, wobeibyte_array[i]==double_array[i]gilt, du also bei dem double-Arrayzugriff die selben Werte erhältst, als wenn du die Werte in einem Byte-Array speichern würdest.Hier eine Beispiel-Lade-Funktion:
template<typename T> std::vector<double> loadFile( const char* path ) { // Datei öffnen std::ifstream file( path, std::ios::binary ); if ( ! file ) throw "file could not be loaded"; // Dateigröße ermitteln file.seekg( 0, std::ios::end ); const std::streamsize file_size = file.tellg(); file.seekg( 0, std::ios::beg ); // Die Dateigröße muss mit der Datentypgröße zusammenpassen if ( file_size % sizeof(T) != 0 ) throw "file is corrupt"; // Datei einlesen std::vector<T> raw( file_size / sizeof(T) ); file.read( reinterpret_cast<char*>(&raw[0]), file_size ); // Alle Werte zu doubles konvertieren und zurückgeben return std::vector<double>( raw.begin(), raw.end() ); } int main() { try { std::vector<double> arr = loadFile<char>( "bla.bin" ); // Oder auch: if ( /*ist byte-Datei*/ ) arr = loadFile<char>( "bla.bin" ); else if ( /*ist short-Datei*/ ) arr = loadFile<short>( "bla.bin" ); else if ( ... // Ausgabe der Werte std::copy( arr.begin(), arr.end(), std::ostream_iterator<double>(std::cout,"\n") ); } catch ( const char* err ) { std::cout << "Error: " << err << "!" << std::endl; } }
-
Hehe, ok. Die Aussage "Speicher die Werte einfach alle in einem double Array" war etwas missverständlich;)
Der von dir gepostete Code würde natürlich gehen, aber mal ehrlich.. elegant ist das nicht. Zunächst mal der eklige reinterpret_cast, dann lädst du alles in einen vector des passenden Typs ein, um die Werte dann wieder in einen double vector zu kopieren. Und die enorme Speicherverschwendung wäre auch ein KO Kriterium für mich (ferner sind Operationen wie mul auf doubles langsamer im Vergleich zu ints oder chars, aber das wäre jetzt nicht ausschlaggebend;)Was ich bräuchte wäre sowas wie dynamische Templates:
Foo Member: array<T> foo;
Foo Ctor: Foo(type t) { foo.setType(t); foo.add(...); }
Aufruf: Foo* f = new Foo(int);Aber sowas geht leider nicht^^
-
SucherDerEleganz schrieb:
Aber sowas geht leider nicht^^
Schau dir vielleicht mal Boost.Any und Boost.Variant an. Aber in deinem Fall gibts eigentlich bessere Möglichkeiten, die hier schon erwähnt wurden...
-
SucherDerEleganz schrieb:
Und die enorme Speicherverschwendung wäre auch ein KO Kriterium für mich (ferner sind Operationen wie mul auf doubles langsamer im Vergleich zu ints oder chars, aber das wäre jetzt nicht ausschlaggebend;)
Genau deswegen braucht man mehr Infos von dir. Sag doch gleich, dass du viele Werte oder wenig Speicher hast und deine Rechenzeit knapp ist. Dann hätte ich mir die ganze Mühe nicht machen brauchen. Gr!

-
Außerdem solltest du natürlich auch erwähnen wie viele Werte du grob verarbeiten musst. Viele überschätzen soetwas. Man sollte zunächst sauberen Code schreiben, bevor man zu solchen Hacks wie void* Zeigern greift. Ist die Stelle im Code wirklich so performancerelevant wie du denkst, hat dein Profiler dir das gesagt? Wenn nicht, nimm Badestrands Variante, dass ist für jeden C++ Programmierer wesentlich verständlicher, als dieses void*-Zeug.
-
Badestrand schrieb:
Genau deswegen braucht man mehr Infos von dir. Sag doch gleich, dass du viele Werte oder wenig Speicher hast und deine Rechenzeit knapp ist.
Völlig unerheblich wieviele es sind. Die bis zu 8 (!) fache Speichermenge zu verbraten ist nicht sinnvoll - egal ob ich nun 1000 Daten oder 10^9 habe.
@Don06: Nein, eher nicht. Ich werde keine 50 Zeilen Code schreiben um Zeilen code zu ändern. Abgesehen davon hat mir noch immer keiner geantwortet, wie ich nun bei Badestrands Template Lösung die Daten in der Klasse speichern soll (sprich: was KONKRET jetzt mein void* foo ersetzen soll)
-
SucherDerEleganz schrieb:
Völlig unerheblich wieviele es sind. Die bis zu 8 (!) fache Speichermenge zu verbraten ist nicht sinnvoll - egal ob ich nun 1000 Daten oder 10^9 habe.
Quatsch. Wenn du für Systeme entwickelst, die in der Regel 1-4 GB Arbeitsspeicher haben sind 20 zusätzliche Kilobytes ein Firlefanz und nicht mal erwähnenswert.
-
Badestrand schrieb:
SucherDerEleganz schrieb:
Völlig unerheblich wieviele es sind. Die bis zu 8 (!) fache Speichermenge zu verbraten ist nicht sinnvoll - egal ob ich nun 1000 Daten oder 10^9 habe.
Quatsch. Wenn du für Systeme entwickelst, die in der Regel 1-4 GB Arbeitsspeicher haben sind 20 zusätzliche Kilobytes ein Firlefanz und nicht mal erwähnenswert.
Die Größe des Caches sollte man schon berücksichtigen. Allerdings ist das nicht besonders relevant:
Die Fragestellung ist immer noch ziemlich unklar - was konstituiert eine elegante Lösung?
Muss die Lösung bestimmten Anforderung bzgl. Geschwindigkeit, Speicherverbrauch, Codestruktur etc. genügen?
Nach 4 Seiten ist immer noch nicht klar, was am Ende herauskommen soll.y = (static_cast<FLOAT*>(foo))[index] * scaleY;Die elementare Frage nach den Datentypen ist immer noch unbeantwortet (das fällt unter schlampige Fragestellung). Damit ist darf sich nat. jeder Poster sein Eigenes heraussuchen. Die Verwendung eines gemeinsamen Datentyps ist dann ein logischer Vorschlag.
-
Bei Leuten die ernsthaft jetzt noch immer nicht meine simple Frage verstanden haben, muss ich wirklich an deren Intelligenz zweifeln. Soll ichs euch in Paint aufmalen?
Und jetzt nehmt mal die Stöcke aus dem Arsch und hackt nicht dauernd so pedantisch auf dem Wort "elegant" rum... meine Fresse. Ich wollte nur wissen ob das in C++ auf EINFACHE WEISE (elegant halt. Das der Code nett und schlicht aussieht. Sprich: Nicht 50 Zeilen Code etc.) geht, dass ich den void* durch was anderes ersetzen kann.
-
SucherDerEleganz schrieb:
Bei Leuten die ernsthaft jetzt noch immer nicht meine simple Frage verstanden haben, muss ich wirklich an deren Intelligenz zweifeln. Soll ichs euch in Paint aufmalen?
Und jetzt nehmt mal die Stöcke aus dem ***** und hackt nicht dauernd so pedantisch auf dem Wort "elegant" rum... meine Fresse. Ich wollte nur wissen ob das in C++ auf EINFACHE WEISE (elegant halt. Das der Code nett und schlicht aussieht. Sprich: Nicht 50 Zeilen Code etc.) geht, dass ich den void* durch was anderes ersetzen kann.
Ja, das geht eleganter!

Entferne einfach dein Brett vor dem Kopf, überleg dir ob du zur Übersetzungszeit oder erst zur Laufzeit entscheiden kannst welcher Datentyp eingelesen werden soll und lies dir den Thread hier nochmal durch, denn er enthält bereits für beide Fälle die entscheidenden Hinweise.
-
SucherDerEleganz schrieb:
...
@Simon2: Was soll f.[index] bedeuten? ...Dass ich mich auch vertippen kann.

SucherDerEleganz schrieb:
...
Vermutlich meinst du v[index], oder?Genau!
SucherDerEleganz schrieb:
...Erstens habe ich ja doch wieder eine Fallunterscheidung drinnen ...
Aber nur genau EINMAL (nämlich beim Einlesen) und da wird eben gemappt zwischen einem "Typkennzeichen", wie Du es (ist zumindest meine Annahme)aus der Datei einliest. Das switch könntest Du noch mit einer map kaschieren, aber sonst wüsste ich keinen Weg, wie Du da drumherumkommen könntest.
SucherDerEleganz schrieb:
...Ich brauche ja einen Container/Array als Member, das mir die Daten aus der Datei hält ...
Diese Anforderung ist mir bei Dir bislang noch nicht aufgefallen.
Die wesentliche Frage hier ist: Befinden sich in Deiner Containerinstanz zu einem Zeitpunkt immer Objekte gleichen Typs ? (also mal ein [int, int, int, ....] und für eine andere Datei ein [float, float, ...])
Oder brauchst Du einen "Mischcontainer" ? (also [int, int, float, string, float, ...])Von Zweiterem würde ich dringend abraten, bei Ersterem fährst Du mit so einer template-Lösung ziemlich gut.
SucherDerEleganz schrieb:
...Bei Templates muss der Typ ja zur Compilezeit feststehen, ...
Das ist aber ein Vorteil und kein Hindernis. So legst Du viele Ablaufpfade bereits zur Compilezeit fest, was
- doppelt Laufzeit spart (weniger Fallunterscheidungen + gute Optimierungsmöglichkeiten für Compiler und
- Fehlermöglichkeiten reduziert (z.B. irgendwo ein vergessener/falscher Typkennzeichner => fällt bereits zur Compilezeit auf bzw. passiert gar nicht, weil das template keinen Typen "vergessen kann").SucherDerEleganz schrieb:
...Und um 2 (!) Zeilen Code, die mir nicht so gefallen...
Oh - Du sparst sehr viel mehr Zeilen! Aus (1+n) "manuellen" Typunterscheidungen (beim Einlesen + bei n Funktionalitäten, die differenzieren müssen) reduzierst Du auf eine. Wenn Du 8 Typen unterscheidest, sind das jeweils 8 Zeilen....
und sobald ein Typ dazukommt, musst Du an jeder einzelnen der (1+n) Stelle diesen nachpflegen.
So habe ich Dein Szenario mit dem (einleuchtenden) Problem verstanden:SucherDerEleganz schrieb:
...
In den Memberfunktionen greife ich dann immer auf das Array zu und muss leider ständig Fallunterscheidungen machen ...(zum einen den void* und dann noch die ständigen ifs())...SucherDerEleganz schrieb:
...Aber wenn es da keine wirklich simple Alternative gibt (wenig Code), dann lass ich einfach so wie es jetzt ist.
Also meine Lösung benötigt definitv weniger Code (viel weniger Code-Dopplung), bietet mehr Sicherheit und ist für Viele leichter zu lesen ("einfacher")....
Aber nun gut, ich muss das nicht anpreisen wie "sauer Bier". So einen "Wasch-mich-aber-mach-mich-nicht-nass"-Trick (oder hier eher "Verrat-mir-wie's-geht-aber-sag-mir-nichts-Neues"), wie Du ihn anscheinend gerne hättest, kann ich leider nicht liefern.
Dein Problem ist übrigens weder exotisch noch rein kosmetischer Natur ... was dazu führt, dass es inzwischen diesen hier verbreiteten Konsens einer "guten Lösung" gibt. Ob Du lieber zu denjenigen zählst, die von dieser Fremderfahrung profitieren oder sie lieber selbst machst, ist Deine freie Entscheidung.
(ich selbst habe auch viel mehr schlechte Erfahrungen machen müssen, als mir lieb war - und hätte mit ein paar mehr gelesenen Büchern mir viel Ärger ersparen können
)Gruß,
Simon2.
-
SucherDerEleganz schrieb:
Bei Leuten die ernsthaft jetzt noch immer nicht meine simple Frage verstanden haben, muss ich wirklich an deren Intelligenz zweifeln.
Meine Güte, schau doch nur, wie viele Vorschläge hier schon gebracht wurden. Aber Ratschläge ohne konkrete Codebeispiele scheinst du ja grundsätzlich zu ignorieren...

SucherDerEleganz schrieb:
Soll ichs euch in Paint aufmalen?
Gerne, wenn es das Verständnis erleichtert. Wobei dein Problem inzwischen eigentlich gelöst sein sollte.
-
SucherDerEleganz schrieb:
Bei Leuten die ernsthaft jetzt noch immer nicht meine simple Frage verstanden haben, muss ich wirklich an deren Intelligenz zweifeln....
Kannst Du natürlich machen - aber Du kannst auch kurz in Erwägung ziehen, dass vielleicht wirklich Deine Fragestellung doch nicht gaaaaanz so eindeutig und allgemeinverständlich ist, wie Du Dir das gedacht hast.
So wie beim "Geisterfahrerphänomen" nicht unbedingt wirklich alle Anderen falsch liegen müssen ....Vermutlich bist Du noch nicht so lange hier im Forum, aber es treiben sich hier (auch in diesem Thread) sehr gute Leute rum (ich zähle mich nicht dazu).
... und spätestens wenn camper, der den C++-Standard rückwärts auswendig draufhat und bei dem ich noch NIE erlebt habe (und ich bin nun auch schon eine längere Zeit hier dabei), dass er eine Programmieraussage revidieren musste, die Fragestellung nicht versteht, würde ich das schon sehr ernst nehmen.
Aber auch das ist Deine freie Entscheidung.Letztlich bleibt's dabei: Wenn diesen Augenblick das Forum für immer abraucht, hast Du weiterhin Dein Problem - und sonst keiner von uns hier.

So - und nu geh' ich ins Bett zu meinem lieben Frauchen.
Nacht,
Simon2.
-
Simon2 schrieb:
... und spätestens wenn camper, der den C++-Standard rückwärts auswendig draufhat und bei dem ich noch NIE erlebt habe (und ich bin nun auch schon eine längere Zeit hier dabei), dass er eine Programmieraussage revidieren musste, die Fragestellung nicht versteht, würde ich das schon sehr ernst nehmen.
Nicht zu viel loben, sonst strengt er sich nicht mehr an.

Also, ich habs schon erlebt.
Trotzdem, es stimmt schon. Der Thread ist beinahe eine Elefantenrunde.

-
Simon2 schrieb:
Diese Anforderung ist mir bei Dir bislang noch nicht aufgefallen.
Ihr wollt mich doch verarschen, oder? So eine Art Aprilscherz. Auf SEITE 1 des Threads ist in meinem Code Sample klar ersichtlich, dass void* data; ein MEMBER der Klasse ist und ich somit also die eingelesenen Daten in der Klasse halten will.
Simon2 schrieb:
Die wesentliche Frage hier ist: Befinden sich in Deiner Containerinstanz zu einem Zeitpunkt immer Objekte gleichen Typs ?
Auch das ist auf Seite 1 klar geklärt. Spätestens mit dem Posting von Badestrand sollte das eindeutig gewesen sein:
Oh, sorry, dann hatte ich das falsch verstanden. Ich dachte, es würden gemischt floats, ints usw drinstehen.
Aus dem Posting ist klar ersichtlich, dass ich KEINE Mischarrays oder sowas brauche. Und dann sagst du mir ein paar Seiten weiter, dass das nicht klar hervorging. Sorry, aber...
Weil das Problem ja immernoch so völlig diffus und undurchschaubar zu sein scheint (
) hier nochmal (ca. zum 3. Mal) der Code wie es im Moment aussieht (vereinfacht):class Foo { private: void* data; DATA_TYPE dataType; public: Foo(DATA_TYPE dataType) { // stream öffnen usw this->dataType = dataType; if(dataType == RAW_F32) { data = new FLOAT[count]; stream.read( (char*)data, count * 4); } else if(dataType == RAW_U8) { data = new BYTE[count]; stream.read( (char*)data, count); } } // In genauer EINER einzigen Methode greife ich nun lesend auf das Array zu: void method() { // ... if(dataType == RAW_F32) v[index].SplineB.y = (static_cast<FLOAT*>(data))[index] * this->scaleY; else if(dataType == RAW_U8) v[index].SplineB.y = (static_cast<BYTE*>(data))[index] * this->scaleY; }Das ist alles. Wie ich es auf mehreren Seiten immer wieder gepostet habe. Und jetzt nochmal meine simple Frage (zum 2. oder 3. Mal): Bei euren Lösungen, durch welchen Datentyp ersetze ich nun void* data (da ich ja die Daten als Membervariable in der Klasse halten will)?
-
Simon2 schrieb:
So - und nu geh' ich ins Bett zu meinem lieben Frauchen.
Ich habe mich dich immer jünger vorgestellt.
(Was wohl am namen liegt, da ich nur jugendliche Simons kenne. :))@SucherDerEleganz :
Ist DATA_TYPE zur Laufzeit bekannt?
Wenn ja: Siehe mein Beispiel auf Seite 1
wenn nein: Siehe mein Kommentar auf Seite 2. (virtuelle Funktionen)class IDataType { public: virtual void read () = 0; virtual IDataType (){} }; class RAW_F32 : public IDataType { public: void read () {} }; class RAW_U8 : public IDataType { public: void read () {} }; ... class Foo { private: std::list<IDataType*> data; public: Foo(std::string type) { if ( type == "RAW_F32") data.push_back (new RAW_F32); else if ( type == "RAW_U8") data.push_back (new RAW_U8); ... } void method() { //gemütlich auf den Container zugreifen und die Schnittstelle benutzen und du hast keine Probleme. }Allerdings vermute ich, dass die Typen bereits zur Compilezeit bekannt sein können, wenn du da ja sowas hast: DATA_TYPE dataType. Aber wie auch immer. Das, was ich jetzt gesagt habe haben schon andere vor mir (+ ich selbst) schon gesagt..
