Zur laufzeit die deklaration bestimmen
-
hallo leute
könnte mir bitte jemand sagen, wie man ein klassen-attribut zur laufzeit festlegen kann? folgendes: ich habe eine schleifen-verschachtelung die wie folgt ausschaut:
void function(/* parameter */) { for(int i = 0; i < OBJECT_DYN_ARRAY.Length; i++;) { for(int j = 0; j < OBJECT_DYN_ARRAY[i]->SEC_DYN_ARRAY_X.Length; j++) { //........ } } }
ich möchte nun zur laufzeit über ein argument, der zweiten for-schleife klar machen, das es sich z.b. um DYN_ARRAY_1 handelt. OBJECT_DYN_ARRAY ist ein dynamisches array welches mehrere klassen instanzen aufgewahrt. die klasse beinhaltet als deklaration drei weitere dynamische arrays. und zwar SEC_DYN_ARRAY_1, SEC_DYN_ARRAY_2 und SEC_DYN_ARRAY_3. der typ spielt nun keine rolle, ich möchte es nur ausführlich schildern.
nun möchte ich eben bei der zweiten schleife zur laufzeit, dass korrekte dynamische array angeben. also z.b. SEC_DYN_ARRAY_1 oder SEC_DYN_ARRAY_2 oder SEC_DYN_ARRAY_3. wie löst man sowas? ich habe schon einiges durchgenommen, wie man das mit dem C++ syntax lösen könnte aber mir kommt nicht in den sinn wie man genau mein problem löst. dazu fehlt mir leider noch der gewisse syntax dazu.
ein zeiger kommt wohl eher nicht in frage, weil das hier falscher syntax wäre:
for(int j = 0; j < OBJECT_DYN_ARRAY[i]->POINTER.Length; j++)
POINTER wäre dann ja ein unbekanntes symbol. mit makros wüsste ich nicht genau wie, wenn es möglich wäre. typedef oder casts macht auch keinen sinn, da ich ja nicht den typ angeben möchte, sondern die korrekte (vorhandene) deklaration. irgend eine idee?
-
Hallo
Du kannst immer Referenzen oder Zeiger verwenden, wobei Referenzen einfacher sind
void function(DEIN_TYP& OBJECT_DYN_ARRAY) { for(int i = 0; i < OBJECT_DYN_ARRAY.Length; i++;) { for(int j = 0; j < OBJECT_DYN_ARRAY[i]->SEC_DYN_ARRAY_X.Length; j++) { //........ } } } ... // Aufruf : function(DYN_ARRAY_1);
Auch Zeiger sind möglich. sollten aber nur verwendet werden wenn dem Aufrufer die Option gegebenen werden soll auch NULL zu verwenden. Wenn immer ein gültiges Array übergeben werden muß, dann verwende Referenzen.
Außerdem must du bei Zeigern auch immer noch dereferenzieren :void function(DEIN_TYP* OBJECT_DYN_ARRAY) { for(int i = 0; i < OBJECT_DYN_ARRAY->Length; i++;) // -> statt . { for(int j = 0; j < (*OBJECT_DYN_ARRAY)[i]->SEC_DYN_ARRAY_X.Length; j++) // OBJECT erst dereferenzen, dann []-Op { //........ } } } ... // Aufruf : function(&DYN_ARRAY_1);
bis bald
akari
-
hallo akari und danke
so wie du es beschreibst ist es kein problem, dass schon. aber: ich möchte ja SEC_DYN_ARRAY_X ersetzen. das wird ja dann mit einem zeiger schon eher unmöglich, es sei denn ich ändere das ganze schleifen und funktions konzept. ich musste gerade feststellen das es mit einem #define doch gehen würde. und zwar so:
#define SEC_DYN_ARRAY SecDynArray1 for(int j = 0; j < OBJECT_DYN_ARRAY[i]->SEC_DYN_ARRAY.Length; j++)
das würde gehen und der compiler hat auch nichts dagegen
aber ist das sauberer C++ syntax? würde mein problem lösen und ich denke mir das bjarne sicher auch berücksichtigt hat, dass ein programmierer auch mal eine namens-ausgabe anstelle eines zeigerzugriffs benötigt.
ich müsste jetzt nur noch wissen wie ich ein #define re-definieren kann. also erst die eigentliche definition:
#define SEC_DYN_ARRAY
und später im code ähnlich wie eine zuweisung, die definition SEC_DYN_ARRAY ändern. wie geht sowas? mit SEC_DYN_ARRAY = SecDynArray1 ist es ja nicht getan.
-
ach moment, dass würde ja nichts bringen da makros ja precompiled sind. ich müsste es ja zur laufzeit haben. wie kann ich sowas anstelle mit einem makro denn lösen, das es mir einfach den namen korrekt ersetzt?
-
Hallo,
was akari IMHO meint: Du übergibst deiner Funktion das dynamische Objekt. Die Funktion übernimmt das Objekt immer unter dem gleichen Namen (siehe Parameterliste im Funktionskopf). Dadurch kannst du in der for-Schleife immer den selben Namen angeben und es wird immer das richtige dynamische Objekt eingesetzt! Damit solltest du das eigentlich lösen können.
Was willst du überhaupt machen?! Das Ganze sieht mir doch irgendwie umständlicher aus, als es eventuell sein müsste...
MfG
-
Hallo
Achso dann hab ich das falsch verstanden. Aber auf jedenfall sind Makros nicht die richtige Wahl, denn Makros werden beim Kompilieren aufgelöst und nicht erst zur Laufzeit. Auch Variablennamen gibt es nicht mehr zur Laufzeit.
Was wir als einfachstes dazu einfällt ist ein zusätzlicher Parameter zur Funktion, der in der Funktion ausgewertet wird und damit über das verwendete Array entscheidet.
Etwas eleganter ist es aber wenn du die Klassenstruktur noch etwas änderst :
// Deklaration innere Typ samt Arraytyp struct SEC { }; typedef std::vector<SEC> SEC_DYN_ARRAY; // Deklaration äußerer Typ struct OBJECT { ... const int SEC_DYN_ARRAY_COUNT = 3; // Anzahl der inneren Arrays pro Objekt SEC_DYN_ARRAY SEC_DYN_ARRAYS[SEC_DYN_ARRAY_COUNT]; // Arrays von Arrays von SEC }; // Funktion void function(DEIN_TYP& OBJECT_DYN_ARRAY, int sec_array) // zusätzlicher Parameter : Index des inneren Arrays { for(int i = 0; i < OBJECT_DYN_ARRAY.Length; i++;) { for(int j = 0; j < OBJECT_DYN_ARRAY[i]->SEC_DYN_ARRAYS[sec_array].size(); j++) { //........ } } } ... // Aufruf : function(DYN_ARRAY_1, 0); // Zählung beginnt bei 0
Ich verwende std::vector anstelle von DYNAMIC_ARRAY, weil das aus dem C++ Standard ist und wesentlich komfortabler ist. Technisch gesehen erfüllt es aber denselben Zweck.
bis bald
akari
-
Hallo
Um die Schleifen noch etwas leserlicher zu machen kann man noch zusätzlich in der inneren Schleife noch eine Referenz verwenden. Dürfte sogar minimal schneller sein
for(int i = 0; i < OBJECT_DYN_ARRAY.Length; i++;) { SEC_DYN_ARRAY& array = OBJECT_DYN_ARRAY[i]->SEC_DYN_ARRAYS[sec_array]; // Zwischenspeichern, aber unbedingt Referenz for(int j = 0; j < array.size(); j++) { // mit array arbeiten } }
Wirklich elegant und optimal wäre natürlich immer std::vector und deren Iteratoren für die Schleifen zu benutzen.
bis bald
akari
-
danke für die hilfe