Unterschiedliche DynamicArrays = Unterschiedliche Operationen?
-
Hallo,
ich verwende mehrere Unterschiedliche DynamicArrays und setze für jedes DynamicArray eine eigene Methode ein, um die Zeiger wieder freizugeben. Frage mich jetzt, ob das wirklich so notwendig ist, oder ob man das nicht für alle DynamicArrays in einer einzigen Methode lösen könnte. z.B. mit einem cast, aber wie?
Und wie sieht das ganze aus, wenn ich Mehrere Methoden dazu verwende, die DynamicArrays zu erweitern? Geht das auch mit nur einer Methode? Das Problem hierbei wären die Klassenelemente. Sprich: Unterschiedliche Typen und Namen. Ist es überhaupt notwendig hier eine einzige Methode anzuwenden? Immerhin nennen sich diese wie folgt z.B.:
SetFiles();
SetPersons();
...
-
Hallo
DynamicArray selber ist ja bereits ein Template, und mit weiteren Template-Funktionen kannst du auch eine allgemeine Löschfunktion schreiben
template <class ElementType> void DeleteElements(DynamicArray<ElementType>& array) { for (int lv = 0; lv < array.Length; lv++) delete array[lv]; array.Length = 0; } ... DynamicArray<Class1*> a; DynamicArray<Class2*> b; DeleteElements(a); DeleteElements(b);
Analog kannst du auch ein Add-Template schreiben.
bis bald
akari
-
Kannst du TR1 oder die boost Bibliotheken benutzen? Mit der Auswahl des entsprechenden Containers brauchst du dir dann um die Speicherverwaltung keine Sorgen mehr zu machen.
-
Hey genial! Danke akari und _DocShoe_. Da ich templates lange kenne aber leider nie damit gearbeitet habe, habe ich mich dazu entschlossen nun endlich mal Templates anzuwenden und siehe da, es ist ganz einfach und genial zugleich. Also mache ich das hiermit nun richtig?
template <class DynArray> void ResetDynamicArray(DynamicArray<DynArray*> pDynArray) { for(int i = 0; i < pDynArray.Length; i++) delete pDynArray[i]; pDynArray.Length = 0; } //calls: ResetDynamicArray(Persons); ResetDynamicArray(Files); ResetDynamicArray(Data);
Spitze! Es gibt nichts was ich mehr hasse, als unnötigen Doppel-Moppel Code zu schreiben. Templates werden mir das Leben erleichtern :). Nur eine Sache ist mir leider nicht ganz klar, nähmlich die Anologie dazu. Speziell, wie kann ich mit einem Template an die Klassenelemente kommen? Diese nennen sich ja bei allen DynamicArrays anders. Also bei der Klasse Person z.B. firstname, surname. Bei der Klasse File z.B. filename, filesize, etc. Wie kann ich nun mit einem Funktions Template an die Namen kommen?
Like:
template <class DynArray, class DynArrayClass> void AddToDynamicArray(DynamicArray<DynArray*> pDynArray, DynArrayClass *pDynArrayClass) { int i = pDynArray.Length; pDynArray[i] = new DynArrayClass(); pDynArray[i]->WELCHER_ELEMENT_NAME = pDynArrayClass->UND_HIER_DER_GLEICHE; }
-
Hallo
Templates können alles verallgemeinen was gleichartig ist bzw. heißt.
class A { int x; }; class B { int x; }; class C { int y; }; template <class Type> foo(Type var) { var.x = 10; } ... A a; B b; C c; foo(a); // geht foo(b); // geht foo(c); // geht nicht, da C keinen Member mit Namen x hat
Mit anderen Worten : Templates können viel aber nicht alles. Falls deine Add-Funktion zu speziell für einen Typ angepasst ist (durch Membernamen), dann bringt es nichts ein Template draus zu machen. Man könnte dann zwar wieder das Template spezialisieren, aber dann ist man in deinem Fall wieder bei einer Funktion pro Typ.
bis bald
akari
-
Wenn ich dich richtig verstehe, geht es für mein Szenario also nicht. Weil jede Methode die ich habe, erzeugt zwar in einem DynamicArray ein neues Element, aber eben mit einer Specifizierter Klasse. Demnach bringt mir ein Template hier nichts oder verstehe ich etwas nicht ganz? Ich stelle mir aber gerade die Frage, wie das der Compiler dann zustande bringt, wenn es um z.B. einen SOAP Dienst geht. Dort werden ja auch die SOAP Elemente vom Compiler, denn DynamicArray Elementen übergeben. Ich glaube das hat mit RTTI zu tun weiss aber da leider viel zu wenig. Jedoch wäre das, was ich suche?
-
Hallo
Um daraus ein sinnvolles Template zu machen muß man eben mit Konstruktoren arbeiten (Außerdem fehlt bei dir noch das Vergrößern des Arrays. Und das DynamicArray muß als Referenz übergeben werden!)
template <class DynArray, class ParType> void AddToDynamicArray(DynamicArray<DynArray*>& pDynArray, ParType par) { int i = pDynArray.Length; pDynArray.Length++; pDynArray[i] = new DynArray(par); }
Wenn nun die Klasse, die als DynArray übergeben wird, einen Konstruktor anbietet, der einen Parameter vom Typ ParType akzeptiert, dann ist dieses Template anwendbar.
bis bald
akari
-
Ach stimmt. Daran habe ich jetzt garnicht gedacht. Du meinst also ich soll von jeder Klasse den Konstruktor mit dem Parameter ParType erweitern und dann die Inizialisierung im jeweiligen Konstruktor mit den korrekten Elementnamen vornehmen? Das macht durchaus Sinn. Danke
-
Hallo
Genau das war mein Konzept.
bis bald
akari
-
Super, Danke. Eine kleine Frage nach am Rande: Sehe ich das richtig, dass man Templates nicht extern nutzen kann? Muss man bei Templates also sowohl die Deklaration als auch die Definition in einem Header machen? Alle Programmteile welche dann dass Template nutzen möchten, holen sich das dann aus dem Header?
-
Hallo
Ja bei Templates muß beim Einsatzort auch die Implementation bekannt sein, nicht nur die Deklaration. Das führt dazu das Templates meist komplett in Header implementiert werden.
bis bald
akari
-
Muss es unbedingt ein DynamicArray sein? Kannst du nicht std::vector benutzen? Die Erfahrung zeigt leider, dass viel zu oft dynamische Objekte benutzt werden, obwohl man das alles durch Container der STL erledigen könnte.
-
Hallo
Das sind doch zwar paar Schuh, dynamische Objekte und std::vector
DynamicArray<Class*> // Aktuell DynamicArray<Class> // ohne manuell dynamische Speicherreservierung std::vector<Class*> // ohne DynamicArray std::vector<Class> // ohne DynamicArray und manuelle dynamische SR
Auch ich empfehle Variante 4. Ohne weitere Nutzung von STL-Vortielen ergibt sich aber aus std::vector alleine noch kein Funktionsvorteil.
bis bald
akari