Unterschiedliche Datentype zur Laufzeit hinzufügen
-
Erklär mal, was du überhaupt tun möchtest. Das klingt mir stark nach schlechtem Design.
-
C und C++ verlangen eine Deklaration der eingesetzten Datentypen. In C++ hast du die Möglichkeit zur Überlagerung und kannst damit einiges anfangen. Bei Klassen kann das schnell zur Knochenarbeit werden. Also teile erst einmal genau mit, was du vorhast und brauchst.
-
Du weißt schon, das du Lua wunderbar in C++ einbetten kannst? Du mußt nicht dein gesamtes Projekt in Lua machen, sondern nur den zu Lua wunderbar passenden Teil. Und C++ kannst du für den Rest nutzen.
-
EduardH schrieb:
Als Ergebnis soll eine Framework entstehen, welches den Benutzer anbietet:
z.B:
1.) Freie Erstellung von Objecten -> Definition der Attributnamen und -Type
2.) Erstellen von Regeln -> z.B: if (O1.Preis > O2.Preis) then O1.Gewicht = O2.Gewicht
3.) Dateneingabe in den Objecten
4.) Abfragen zu den Daten
5.) Simulation (Soetwas wie selbstständiges Agieren und sehen wie sich die Daten ändern)
6.) SourceCode generator für Objecte (Wunschdenken
)
Eine fertige Schnittstelle habe ich noch nicht erstellt, da ich noch am Anfang steheDann fängst Du mit dem falschen Ende an, fürchte ich.
- Schreibe einen mathematischen Parser, der nur double berechnenm kann.
- Schreibe einen neuen, der double und int kann.
- Bastele weitere Schlüsselwörter if/the, while, print ein.
- Wenn der Parse-Baum aus polymorphen C++-Objekten besteht, ist 6.) extrem einfach nachzurüsten.
-
314159265358979 schrieb:
Erklär mal, was du überhaupt tun möchtest. Das klingt mir stark nach schlechtem Design.
Ah, die Design Keule mal wieder. Ist das Dot's Zweitnick?
-
BAUMKOPFHOLZFAUST schrieb:
314159265358979 schrieb:
Erklär mal, was du überhaupt tun möchtest. Das klingt mir stark nach schlechtem Design.
Ah, die Design Keule mal wieder. Ist das Dot's Zweitnick?
Wer ist Dot?
Die Design-Keule ist hier angebracht.
-
volkard schrieb:
Wer ist Dot?
Ein User mit dem Nick 'Dot', Watson!
-

volkard schrieb:
EduardH schrieb:
Als Ergebnis soll eine Framework entstehen, welches den Benutzer anbietet:
z.B:
1.) Freie Erstellung von Objecten -> Definition der Attributnamen und -Type
2.) Erstellen von Regeln -> z.B: if (O1.Preis > O2.Preis) then O1.Gewicht = O2.Gewicht
3.) Dateneingabe in den Objecten
4.) Abfragen zu den Daten
5.) Simulation (Soetwas wie selbstständiges Agieren und sehen wie sich die Daten ändern)
6.) SourceCode generator für Objecte (Wunschdenken
)
Eine fertige Schnittstelle habe ich noch nicht erstellt, da ich noch am Anfang steheDann fängst Du mit dem falschen Ende an, fürchte ich.
- Schreibe einen mathematischen Parser, der nur double berechnenm kann.
- Schreibe einen neuen, der double und int kann.
- Bastele weitere Schlüsselwörter if/the, while, print ein.
- Wenn der Parse-Baum aus polymorphen C++-Objekten besteht, ist 6.) extrem einfach nachzurüsten.Naja ich fing bei folgenden Ende an
Der Benutzer kann sich sein Attribute selbst definieren.
z.B: Datentype, Minwert, MaxWert, Name, Anmerkung und automatische id Vergabe.
Diese Informationen sind als leicht als Object zu definieren und liegen in einer map um über die id zugreifen zu können.Aus den definierten Attributen baut er jetzt sein Object zusammen.
Hier ist mein einziges Problem in der Speicherung, daher meine verschiedenen Ansätze. Vieles lässt sich ja einfach über templats erledigenMit allen anderen Punkten (2-6) gibt es kein Problem!!!!
Die Idee bereits nur double zu berechnen, bringt mich auf folgendes

Die Anzahl der möglichen Datentypen kann auf 3 reduzieren werden
map(double)
mab(string)
map(object)Das so zumachen lag mir fern!
Historisch bedingt (2k Ram war mal viel) bin ich ein Sparefroh bezüglich Speicher und Laufzeit.Besten Danke!
Eduard@314159265358979
Die Design Keule sollte erst ausgepackt werden, wenn ein Design erstellt wurde!Nicht alles was flexibel/generisch sein soll, ist auch ein Fehler.
-
Ich habe dein Design lediglich in Frage gestellt, nicht gesagt dass es schlecht ist. Und für mich sieht das immer noch komisch aus, ich kann aber auch mit deiner Beschreibung nichts anfangen.
-
@314
"Verstehe ich nicht" => "klingt nach schlechten Design"
1A Logik
-
314159265358979 schrieb:
Ich habe dein Design lediglich in Frage gestellt, nicht gesagt dass es schlecht ist. Und für mich sieht das immer noch komisch aus, ich kann aber auch mit deiner Beschreibung nichts anfangen.
Ich versuche es mal anders zu beschrieben.
Es gibt ein Basisklasse Object, als einfaches Beispiel:
class Object { private: std::string Vorname; std::string Nachname; std::string Geburtsdatum; public: bool setVorname(std::string){} // und was so alles benötigt wird }Diesem Object sollen zur Laufzeit neue Variablen/Member hinzugefügt werden.
Die Datentypen sind zur Compilezeit bekannt!
Die Anzahl der Member ist zur Compilezeit nicht bekannt!Die erlaubten Datentype sind in meinem Fall:
int
bool
double
std::string
Referencen auf das Basisobject bzw. abgeleitete Objecte der BasisDies würde, da C++ streng typisiert ist, für jeden Datentype einen eigenen Container erfordern.
Für jeden möglichen Datentype muss ein Container in die class integriert werden
Templates helfen mir den geschriebenen Code zu vereinfachen, die Anzahl der Container bleibt aber gleich.Die Basisklasse Object würde verreinfacht so aussehen
class Object { private: std::string Vorname; std::string Nachname; std::string Geburtsdatum; std::map<int, int> intMap; std::map<int, bool> booMap; std::map<int, double> booMap; std::map<int, std::string> strMap; std::map<int, Object> objMap; public: bool setVorname(std::string){} // und was so alles benötigt wird }Daher habe ich mir mehrere Lösungsansätze überlegt um dennoch neue Member hinzuzufügen ohne gleich eine Container-Inflation zu erhalten
Und diese Lösungsansätze gepostet mit der Bitte um Hilfe!War das jetzt verständlich?
-
volkard schrieb:
BAUMKOPFHOLZFAUST schrieb:
314159265358979 schrieb:
Erklär mal, was du überhaupt tun möchtest. Das klingt mir stark nach schlechtem Design.
Ah, die Design Keule mal wieder. Ist das Dot's Zweitnick?
Wer ist Dot?
Die Design-Keule ist hier angebracht.Das bin wohl ich. Und nein, 314159265358979 bin nicht ich. Aber ich hätt die Design Keule auch ausgepackt bzw. tus gleich mal.
@EduardH: deiner Beschreibung nach find ich dass dein Vorschlag prinzipiell mal eine Lösung ist, wobei ich statt einer map einfach einen vector verwenden würde falls es sich einrichten lässt dass die keys aufsteigende Integer sind. Allerdings find ich das Problem an sich ein wenig merkwürdig, warum genau musst du denn diese Daten hinzufügen, was soll mit denen mal geschehen? Ein Objekt das für sämliche Member Getter und Setter anbietet ist imo irgendwie was ziemlich kaputtes.
-
hustbaer schrieb:
@314
"Verstehe ich nicht" => "klingt nach schlechten Design"
1A Logik
Das Bedürfnis, boost::any zu verwenden ist fast immer schlecht

@Threadersteller: Jetzt ist mir klar was du haben möchtest. Allerdings finde ich es, wie dot, auch sehr merkwürdig.
-
314159265358979 schrieb:
hustbaer schrieb:
@314
"Verstehe ich nicht" => "klingt nach schlechten Design"
1A Logik
Das Bedürfnis, boost::any zu verwenden ist fast immer schlecht

Dinge zu beurteilen, bevor man sie versteht, ist fast immer schlecht.
Dinge nachzuplappern, bevor man selbst damit Erfahrung machen konnte, ist auch nicht optimal.Und designe bitte selbst erstmal ein paar Dinge (und implementiere diese Designs dann auch), bevor du mit Aussagen wie "schlechtes Design" um dich wirfst.
Null Erfahrung, aber immer grosse Klappe - das nervt schon ordentlich.
-
@Alle Design Zweifler :p :
Was ist es: Ein Framework für Planspiele
Wie schon geschrieben:
1.) Freie Erstellung von Objecten -> Definition der Attributnamen und -Type
2.) Erstellen von Regeln -> z.B: if (O1.Preis > O2.Preis) then O1.Gewicht = O2.Gewicht
3.) Dateneingabe in den Objecten
4.) Abfragen zu den Daten
5.) Simulation (So etwas wie selbstständiges Agieren und sehen wie sich die Daten ändern)
6.) SourceCode generator für ObjecteZweck:
Es soll dem Benutzer bei Durchführung von Planspielen unterstützen.
Edit: http://de.wikipedia.org/wiki/Planspiel
Dazu muß es möglich sein die einzelnen Objekte, je nach Anforderung und Thema, flexibel erstellen zu können.
Egal ob das Objekt ein Auto, Haus, Zug, Baum, Karotte, Aktienkurs, Krankheiten, Telefon, Schneefall, Täter, Schulnoten, Tageszeit , Berge, … ist.Alles ist möglich, nix is fix! -> Ich bin nicht dazu in der Lage das in Klassen ohne flexible Attribute/Member zu bekommen.
Ein nicht so komplexes Thema wo flexibilität erforderlich ist:
Möglichweise kennt wer Gesprächsleitfäden wie sie in CallCentern verwendet werden!?
Und nein, ich mache hier nichts für ein CallCenter oder andere Institution die unsere Telefone zu allen möglichen und unmöglichen Zeiten erklingen lassen!Map ist hier richtig. Der key(int) zu den Atrributen ist Global für alle Objekte.
So ist auch gesichert das in jeden Object der key=17 die selbe Bedeutung hat.Ist's jetzt Klar?
-
Ok, dann ist boost::any wohl eine Lösung. Wobei eine Skriptsprache vermutlich die mit Abstand beste Lösung wäre. Eine Alternative wäre vielleicht noch ein System wie das folgende:
class IEvaluable { public: virtual int asInt(int v) = 0; virtual float asFloat(float v) = 0; ... }; class IComparable { public: virtual int compare(int v) = 0; virtual int compare(float v) = 0; ... }; class IAttribute : virtual public IComparable, virtual public IEvaluable { public: virtual int compare(IComparable& v) = 0; virtual bool setValue(const IEvaluable& v) = 0; }; template <typename T> class Attribute : public IAttribute { private: T value; public: int compare(int v) {...} int compare(float v) {...} int compare(const IComparable& v) { return v.compare(value); } bool setValue(const IEvaluable& v) {...} }; class Rule { public: virtual void evaluate() = 0; }; class Object { std::unordered_map<std::string, IAttribute*> attributes; public: IAttribute* getAttribute(const std::string& name) {...} };
-
Wenn ein Attribut nur wenige bekannte Typen haben kann, dann wäre evtl. auch boost::variant<> eine Möglichkeit. IMO dann besser als boost::any, wenn man die Möglichkeit gar nicht braucht da *alles* reinstecken zu können.
Type-Safety ist dann auch sehr gut. Und es gibt fertige Hilfsfunktionen wie boost::apply_visitor, so dass man das Type-Dispatching nicht selbst machen muss.
Eine Lösung über "normale" Laufzeitpolymorphie, wie die von dot, ist sicher auch eine gute Möglichkeit.
Trotzdem bin ich immer noch der Meinung, dass hier eine Sprache wie Lua oder Python angesagt wäre. Ganz einfach weil Scriptsprachen u.a. genau dafür gemacht wurden.
Und wieso das Rad neu erfinden? Gerade was die Punkte (2) und (5) angeht: da müsstest du eine Eigene Syntax definieren, einen Parser + Interpreter dafür schreiben, die so entstandene Mini-Sprache dokumentieren und den Leuten beibringen die das verwenden wollen.
Lies dir mal das da durch: http://en.wikipedia.org/wiki/Inner-platform_effectGerade Lua ist sehr einfach ein C++ Programme einzubetten, kann einfach "dicht" gemacht werden (so dass ein Script keine unerwünschten Dinge machen kann wie Files lesen/schreiben/löschen etc.), und bietet im Prinzip alles was gefordert wurde - bis auf Punkt (6).
Wobei mir Punkt (6) auch nicht 100% klar ist: was für Code soll generiert werden? C++ Code? Code der wieder auf die "dynamische Attribute" Implementierung zurückgreift? Oder Code für "normale" C++ Objekte (ohne die "dynamische Attribute" Sache), deren Funktionalität den "dynamisch" definierten entspricht? ...?
Und was soll mit dem generierten Code dann gemacht werden, was ist der Zweck dieser Funktion?Willst du vielleicht ein Rapid-Prototyping System basteln, aus dessen "Source" (Definitionsfiles, Input, wie auch immer man es nennen will) dann ein C++ Gerüst generiert werden kann, so dass man es als Basis einer reinen C++ Implementierung verwenden kann?
Aber ziemlich egal was Punkt (6) nun genau bedeutet, auch das liesse sich sicher mit Hilfe von Lua oder einer anderen Scriptsprache umsetzen. Nur müsste man es halt selbst dazuprogrammieren. Was in Summe aber vermutlich viel weniger Action ist, als das ganze System in C++ selbst zu schreiben.
Nochwas zu Lua: du kannst dir da relativ frei aussuchen, wie viel du wirklich in Lua implementieren willst. Theoretisch kannst du Lua in C++ einbinden, und kaum mehr damit machen, als dessen "Table" Implementierung zu verwenden - da die ziemlich genau das ist, was du willst: Objekte mit dynamischen "Membern". Das andere Extrem wäre alles komplett in Lua zu schreiben. Und alles dazwischen ist auch möglich.
-
Vor http://en.wikipedia.org/wiki/Inner-platform_effect hatte ich auch schon leichte Panik.
Nach einen Lua Wochende, bekenne ich folgendes:
Ich wurden vom Lua Saulus zum Paulus!
.
Der Mix auc C++ und Lua erspart mir wirklich einiges an Arbeit und Ärger.Zu Punkt 6: Es war als Performace-Option gedacht. Jetzt kein Thema mehr.
Ich bedanke mich hiermit noch mal!

MlG
Eduard