Hi,
also ich habe ne Idee aber bei der Umsetzung bin ich mir net ganz sicher
ob es da nicht bessere gibt?
Ich würde gern einen Array haben, der Daten verschiedener Datentypen
(int,float..) halten kann.
Evtl. wird es mi dem Code deutlicher was ich will:
1
typedefstruct
2
{
3
int8_ta[3];
4
uint16_tb[3];
5
floatc[3];
6
}ComplexDataType;
1
// Template beispiel
2
3
template <class DATA_1,uint8_t size_1, class DATA_2,uint8_t size_2 , class DATA_3, uint8_t size_3>
4
class ComplexDataType
5
{
6
DATA_1 a[size_1];
7
DATA_2 b[size_2];
8
DATA_3 c[size_3];
9
10
};
Das ist noch nicht ganz meine Lösung, da ich die Größen der Arrays
varrieren will und zudem es sein kann dass es stat float mal uint32_t
sein soll.
Ich dachte an sowas wie Template-Klassen (s. Beispiel).
Das ganze soll letzendlich auf einem Controller laufen.
Gibt es alternativen für mein Problem oder bedenken für die Template
lösung?
Gruß
GoldenEyes
Was ist überhaupt das Problem?
Wie sollen wir wissen ob die Lösung richtig oder auch nur
verbesserungswürdig ist, wenn wir garnicht wissen wofür das eine
Lösung sein soll?
Stell Dir vor, jemand kommt zu Dir, hält Dir eine Rohrzange und einen
Maulschlüssel entgegen und wünscht von Dir zu wissen, was er verwenden
soll.
Da würdest auch sagen: Kommt darauf an, wofür!
Srry.
Also ich habe Daten von Sensoren (SensorData) und Steuerdaten
(ControlData), die aus verschiedenen Datentypen bestehen sollen damit
ich diese an die Regelung wie folgt übergeben kann:
Je nach dem welche Regelung (hier mit XY und ZZ bez.) gewünscht ist
werden die entsprechenden Daten übergeben!
Hoffe jetzt etwas klarheit verschafft zu haben!
Hm. Nun haben wir noch mehr Teile der Lösung. Aber immer noch keine
Angaben zum Problem.
Ich habe aber auch keine Lust nochmal nachzubohren.
Klare und verständliche Darstellung von Problemen ist Teil der Kunst und
kein überflüssiges Übel.
Um Dich nicht ganz ohne was zu lassen werfe ich mal das Stichwort
"unions" in den Raum. Pass auf das es Dich nicht beisst. :-)
Viel Erfolg.
Ja, also das Problem habe ich schon im ersten Beitrag geschildert!
Ich habe mich für die Templatevariante entschieden, dennoch Danke ich
dir für deine Bemühungen.
Unions sind mir nicht fremd, aber bringen tuht mir das nicht(zum. wüsste
ich nicht wie).
Gruß
GoldenEyes
Die Lösung für dein Problem lautet höchst wahrscheinlich: Basisklasse +
entsprechende Ableitungen dafür.
In den meisten Fällen, in denen du in C++ versucht bist zu schreiben
if( Typ der Daten ist nada )
mach was
else if( Typ der Daten ist juhu )
mach was
else if( Typ der Daten ist schnutzelbrutz )
mach aber sowas von ganz was anderem
lautet die C++ Lösung: Polymorphismus mit virtuellen Funktionen.
Um nochmal zu meinem Template zurück zukommen;
Also so könnte ich mir jede beliebige (fast) Kombination von Daten
erstellen oder übersehe ich etwas???
Mir geht es nur um den DatenType, die Funktion sind bei mir als Template
realisiert, die jeweils die grundtypen unterstüzen!
Gruß
Karl Heinz Buchegger schrieb:> lautet die C++ Lösung: Polymorphismus mit virtuellen Funktionen.
Dies hätte den nachteil dass ich für jede Kombination (sind zwar nicht
so viele) eine funktion erstellen müsste (obgleich durch
vererbung),Template ist da ehr das richtige.
goldeneyes1987 schrieb:> Mir geht es nur um den DatenType, die Funktion sind bei mir als Template> realisiert, die jeweils die grundtypen unterstüzen!> Gruß
Also das ganze könnte sogar so aussehen:
1
voidwinkel_regler(ComplexDataType*a);
2
voidabstands_regler(ComplexDataType*a);
Jetzt könnten die Funktionen jeden beliebigen Datentype übergeben
bekommen;
Intern nutzt die Funktion nur das von TEST1 was sie benötigt!
Beispiel:
1
ComplexDataType*<int,3,int,3,int,1>TEST1;
2
...
3
/*
4
in TEST1 werden jetzt winkelpositionen(3Achsen), winkelgeschwindigkeiten(3Achsen) und abstand zu einem gegenstand gespeichert.
5
*/
6
...
7
winkel_regler(TEST1);
8
abstands_regler(TEST1);
9
..
10
// jeder Regler weiss worauf er zugreifen muss.
11
// so kann ich alles Zustandsinformation zentral in einer Instanz speichern!
goldeneyes1987 schrieb:> Ich würde gern einen Array haben, der Daten verschiedener Datentypen> (int,float..) halten kann.>> Evtl. wird es mi dem Code deutlicher was ich will:> typedef struct> {> int8_t a[3];> uint16_t b[3];> float c[3];> } ComplexDataType;
nun ja, was du hast ist eben kein Array, das verschiedene Datentypen
halten kann, sondern schlicht eine Struktur voller Arrays. Läuft
irgendwie darauf hinaus, dass du eine "allwissende" Struktur
erschaffen willst, von denen die jeweiligen Regler oder was du da baust,
ein Stückchen auswerten.
Mein erster Gedanke war in Richtung echter heterogener Arrays, wie sie
jede moderne Skriptsprache kennt. Zum Beispiel in Python
s = filter(lambda x: type(x)==str, ["1",1.0,1])
oder
s = ["1",1.0,1].reject {|x| x.class != String} in Ruby
In C gibt es das so nicht. Was auch gut ist.
Nachbauen lässt sich das dennoch irgendwie über einen Container
aus void* Zeigern. std::vector<void*> vielleicht. Oder vector von
smart pointern. So elegant wie bei Skriptsprachen wird es ganz sicher
nicht ;)
Daniel schrieb:> Nachbauen lässt sich das dennoch irgendwie über einen Container> aus void* Zeigern. std::vector<void*> vielleicht. Oder vector von> smart pointern. So elegant wie bei Skriptsprachen wird es ganz sicher> nicht ;)
Ja genau, und in C++ kann man void* mit hilfe von Templates ersetzen.
goldeneyes1987 schrieb:> Ja genau, und in C++ kann man void* mit hilfe von Templates ersetzen
die "Magie" der templates liegt eher in compile time Modifizierungen
des Codes, um diesen die Schnittstellen typsicher zu machen.
void* kann hingegen zu runtime zu allen erdenklichen Mittel greifen.
Wie auch immer. Ich habe nochmal deine Postings gelesen und glaube
die sauberste Lösung wäre die vom Karl Heinz. Sauber im Sinne möglichst
wenig Querabhängigkeiten. Wenn alles in der grossen Datenstruktur
steckt,
weiß dein ReglerX was er benötigt, du wirst aber wahrscheinlich in einem
Jahr dieses Wissen nicht mehr haben ;) Auch grosse switch/case
respektive
if/else Kaskaden müssen zentral gepflegt werden, wobei in meinen Augen
das immer noch besser ist, als allen Reglern alle Daten zu geben.
Bei gemeinsamen Abstammung können andere Regler ins System untergejübelt
werden, wenn die Schnittstelle aus virtuellen Funktionen besteht.
goldeneyes1987 schrieb:> goldeneyes1987 schrieb:>> Mir geht es nur um den DatenType, die Funktion sind bei mir als Template>> realisiert, die jeweils die grundtypen unterstüzen!>> Gruß>> Also das ganze könnte sogar so aussehen:>
1
>
2
>voidwinkel_regler(ComplexDataType*a);
3
>voidabstands_regler(ComplexDataType*a);
4
>
>> Jetzt könnten die Funktionen jeden beliebigen Datentype übergeben> bekommen;> Intern nutzt die Funktion nur das von TEST1 was sie benötigt!
Na, dann mach mal.
Wenn du es hinbekommen hast, zeig mal. Das würde ich gerne sehen, wie du
untempletierte Funktionen schreibst, die ein nicht weiter ausgeführtes
Template als Argument nehmen und da auch noch sauber drauf zugreifen.
> winkel_regler(TEST1);> abstands_regler(TEST1);> ..> // jeder Regler weiss worauf er zugreifen muss.> // so kann ich alles Zustandsinformation zentral in einer Instanz> speichern!
Hier liegt schon der erste Denkfehler in einer OOP Welt.
Es gibt keine Funktion winkel_regler
Wohl aber gibt es ein Regler Objekt, instanziiert von einer Regler
Klasse, welche selber weiß, welche Daten (+Datentypen) es benötigt und
daher die entsprechenden Member besitzt.
Wenn du OOP ernst nimmst, dann gibt es keine Funktionen mehr. Es gibt
nur noch Objekte und diese Objekte
* kümmern sich um sich selbst
d.h. das Objektt selbst hält die Daten, die es zur Arbeit benötigt
* verstehen Befehle
die Befehle sind die Memberfunktionen.
Solange du nicht von der Sichtweise abrückst, dass es da einen Satz
Daten gibt und du schreibst Funktionen, die irgendwie diese Daten
manipulieren, bist du noch nicht in OOP angekommen. Das ist kein
Vorwurf. Gerade Leute, die mit funktionalen Programmiersprachen groß
geworden sind, tun sich da schwer, die Denkweise umzustellen. Ich hab
fast 3 Jahre gebraucht, bis ich aufgehört habe 'C mit Klassen' zu
programmieren und den Umstieg nach OOP komplett und mit allen
Konsequenzen vollzogen habe.
Karl Heinz Buchegger schrieb:> Wenn du es hinbekommen hast, zeig mal. Das würde ich gerne sehen, wie du> untempletierte Funktionen schreibst, die ein nicht weiter ausgeführtes> Template als Argument nehmen und da auch noch sauber drauf zugreifen.
Du hast natrülich recht, das geht so nicht!
Aber so:
Zudem stimme ich auch dem zweiten Beitrag zu.
Ich sehe auch das die Lösung wie ich sie hier oben beschrieben habe, bei
einem wachsenden Datentype (angle, angle_velocity, position,
accelertion, trans_velocity, ...) einen risen "Rattenschwanz" mit sich
bringen würde!
Ich habe momentan aber keine bessere oder überhaupt ne Lösung die
letzendlich das löst!?!
goldeneyes1987 schrieb:> Ich habe momentan aber keine bessere oder überhaupt ne Lösung die> letzendlich das löst!?!
Was ist das Problem genau, welches du lösen willst.
(Also nicht, welche Lösung schwebt dir vor und welche Probleme siehst du
bei dieser5 Lösung, sondern aus größerer Entfernung: Was ist dein
Problem?)
Als die Software besteht aus mehreren Modulen, mindestens :
Sensormodul
Steuerungsmodul
Zustandsmodul
Regelungsmodul
Das Sensormodul liefert mir einen Vektor mit Informationen, dessen Größe
und Datentype variieren kann.
Das Zustandsmodul nimmt sich diesen Vektor und errechnet daraus
Zustandsgrößen, dessen Größe und Datentype nicht gleich sind.
Das Regelungsmodul bekommt einen Vektor vom Steuerungsmoudl sowie die
Zustandsgrößen.
Eine "Schnittstellen"-Klasse CotrolRequest erhält alle Daten und reicht
sie an die jeweiligen speziischen Regler weiter.
Bis jetzt hatt ich das so geregelt:
also ich muss immer als benutzer sagen welchen Regler ich gerade
ansprechen will da der Zustandsvektor (states) einem bestimmen datentype
hat, was ich aber nicht will.
Ich weiss nicht ob dies das Erklärt was ich versuche zu übermitteln?
Aber ich hoffe es!
Jetzt können sich die Datentypen (Inputs,Sensor und co.) beliebig ändern
und ohne Einfluß auf andere Member-Funktionen. Da z.B die Funktion
angle_velocity(..) immer nur auf "angle" und "angle_velocity" zugreift.
Hat jemand dennoch einen Einwand warum dies so nicht gemacht werden
solte (im Kontext mit µC oder anderer Natur) ??
Gruß
GoldenEyes
Karl Heinz Buchegger schrieb:> Wenn du OOP ernst nimmst, dann gibt es keine Funktionen mehr. Es gibt> nur noch Objekte und diese Objekte> * kümmern sich um sich selbst> d.h. das Objektt selbst hält die Daten, die es zur Arbeit benötigt> * verstehen Befehle> die Befehle sind die Memberfunktionen.
Gegenbeispiel: CLOS.