Pointer auf Klasse aus Template
-
Hallo Zusammen,
Ich habe eine Frage im Bezug auf Klassentemplates. Ich habe mir eine einfache Klassentemplate "DBResArray" geschrieben,als Container, die andere Klassen beinhalten kann. Die DBResArray sieht so aus:
template<class T, int size> class DBResArray { T array[size]; public: T& operator[](int index){ return array[index]; } int length() const {return size; } };In einer anderen Klasse habe ich versucht, dazu passende "createArray" Funktion
zu schreiben was einen Pointer auf die DBResArray zurueckgeben soll.//..vom outdlg.h DBResArray<DBResElement,int>* createTestArray(int size); //..vom outdlg.cpp DBResArray<DBResElement, int>* OutDlg::createTestArray(int num){ DBResArray<DBResElement, num> test; return &test ; }Nun wenn ich es compiliere, der Compiler von vstudio05 spuckt ein Duzend Fehlern mit:
error C2975: 'DBResArray' : invalid template argument for 'size', expected compile-time constant expression..
Deswegen die Frage, woran scheitert der Compiler? Ich vermute dass ich mit der
Rueckgabedefinition 'DBResArray<DBResElement, int>*' etwas falsches mache..
ich bin mir allerdings nicht sicher.Danke im voraus,
-
Das compiliert nicht, weil ein Integer - wie Dir dein Compiler schon sagt - keine Konstante ist (weder compiletime noch runtime) und damit als bound einer Arraydeklaration nicht zulässig. Wie man aber einen konstanten Ausdruck übergibt: gute Frage - wahrscheinlich garnicht.
Desweiteren gibt deine
OutDlg::createTestArray( )die Adresse einer lokalen Variable zurück, die nach der Rückkehr aus der Funktion Asche ist.Mir erschließt sich irgendwie der Sinn nicht. Du Kapselst ein simples Array brichst dir Kapselung durch die Rückgabe einer non-const reference deines
operator[ ]?Welches Problem versuchst Du mit diesem Konstrukt zu lösen?
cheers, Swordfish
-
Hallo Swordfish,
Swordfish schrieb:
Welches Problem versuchst Du mit diesem Konstrukt zu lösen?
Ich moechte einen Array von DBResElement Instanzen erstellen, dessen Laenge
dynamisch bestimmt werden soll. Deswegen brauche ich fuer meinen Container
DBResArray denoperator[]. Sowie ich verstanden habe, ist Erstellung
einer Klassentemplate der einfachste Weg.. Oder gibt's eine Alternative?Die Verkapselung sieht natuerlich beim ersten Blick unnoetig aus. Nun, die
Initizializierung der Elemente(DBResElement) des Arrays(DBResArray) wird auch
inOutDlg::createTestArray( )ausgefuehrt. Zum anderen wird die Code
dadurch lesbarer.Gruss,
jsbach
-
jsbach schrieb:
Hallo Swordfish,
Swordfish schrieb:
Welches Problem versuchst Du mit diesem Konstrukt zu lösen?
Ich moechte einen Array von DBResElement Instanzen erstellen, dessen Laenge
dynamisch bestimmt werden soll. Deswegen brauche ich fuer meinen Container
DBResArray denoperator[]. Sowie ich verstanden habe, ist Erstellung
einer Klassentemplate der einfachste Weg.. Oder gibt's eine Alternative?Den new Operator? Mit Templates wird das nicht vernünftig funktionieren, da du schon beim Compilieren festlegen musst, wie groß das Array sein soll.
Nimm am besten std::vector als Container. Dann hast du das Problem nicht.
-
Hallo ProgChild,
ProgChild schrieb:
Den new Operator? Nimm am besten std::vector als Container. Dann hast
du das Problem nicht.Danke, habe ich gemacht & funktioniert.
ProgChild schrieb:
Mit Templates wird das nicht vernünftig funktionieren, da du schon beim Compilieren festlegen musst, wie groß das Array sein soll.
In der Tat.. Denn wenn ich
DBResArray<DBResElement, 10>*in der
Funktionssignatur angebe, dann klappt es auch. Dabei ist mir von Nachteil, dass
ich ploetzlich einen Array zur Compilierzeit definieren muss.Wozu ist Klassenemplate gut, wenn es keine dynamische Parametrisierung
unterstuetzt?Gruss,
jsbach
-
jsbach schrieb:
Wozu ist Klassenemplate gut, wenn es keine dynamische Parametrisierung
unterstuetzt?Zum Beispiel bei der Verwendung in std::vector? Es geht darum, bestimmte Dinge allgemein zu programmieren, z.B. eine Container-Klasse, aber nicht darum, dynamische Elemente der Sprache hinzuzufügen. Dafür gibt es Polymorphie und Speicherreservierung mit new.
-
Wozu ist Klassenemplate gut, wenn es keine dynamische Parametrisierung
unterstuetzt?Man kann sehr viele schöne Sachen damit machen.
Ein kleines Beispiel, dass hier auch schön zum Thema passt.
Wenn du den vector betrachtest wirst du merken, dass er einige Vorteile gegenüber dem normalen array hat.Zum Beispiel das Iterator Interface.
Ich finds toll, dass ich beim vector einfach schreiben kann:
//... typedef std::vector<int> Container; typedef Container::iterator Iterator; Container vec,vec2; //... //alle objekte aus vec nach vec2 bis zu einem bestimmten element suchen Iterator pos=find(vec.begin(),vec.end(),foo); std::copy(vec.begin(),vec.pos(),std::back_insert_iterator(vec2));mit nem array ist das nicht ganz so schön
int vec[10]; //... int* pos=find(vec,vec+10,foo); //uswGut, vielleicht siehts auf dem ersten Blick schöner aus ;). Das Problem ist,dass wenn du die größe des array änderst, du das auch in find machen musst. Und das ist fehleranfällig.
Deshalb haben findige Programmierer einen array wrapper geschrieben. verhält sich haargenau wie ein array, aber hat das Iterator Interface
typedef array<int,10> Container; typedef Container::iterator Iterator; Container vec; //... Iterator pos=find(vec.begin(),vec.end(),foo); //uswUnd zum Beispiel genau hier brauchst du diese template argumente, denn überall wo du vorher ein statisches array genutzt hast, kannst du jetzt diese Klasse nutzen.