Verbesserung an Template Klasse gegen Array Überlauf
-
template<class typ,int size> class MyArray {
warum ist size ein template-argument? kannst doch beruhigt die initial size auf 64 festegen oder als konstruktorargument nehmen. vorteil: nicht jedes array braucht eigenen code und die exe wird kleiner, das programm am ende scneller.
MyArray(); MyArray(const MyArray &Array_kopie); MyArray(typ* arr); typ operator=(const MyArray& a); typ &operator[] (unsigned int i); const typ &operator[](unsigned int i) const; ~MyArray() { delete [] array; }
besser, man macht konstruktoren, zuweisungsop und dtor zusammen.
MyArray(); MyArray(typ* arr); MyArray(const MyArray &Array_kopie); typ operator=(const MyArray& a); ~MyArray() { delete [] array; } typ &operator[] (unsigned int i); const typ &operator[](unsigned int i) const;
und der rückgabetyp des op= ist gelinde gesagt gewagt.
template<class typ,int size> MyArray<typ,size>::MyArray() { aktSize=size; array=new typ[size]; }
leider muss das umgeschrieben werden zu
template<class typ,int size> MyArray<typ,size>::MyArray() :array(new typ[size])//das hier wichtig für wenn exceptions ,aktSize(size) { }
template<class typ,int size> MyArray<typ,size>::MyArray(typ* arr) { aktSize=size; array=new typ[size]; for(int i=0;i<size;i++) array[i]=arr[i]; }
naja, wollen wir nicht doch lieber begin und end übergeben? so isses ein wenig komisch.
template <class typ,int size> const typ &MyArray<typ,size>::operator[](unsigned int i) const { if(i<aktSize) return array[i]; else throw out_of_range("Out of Range !!!"); }
was soll das denn? das widerstebt mir. irgendwas ist da ganz komisch.
return *this; // Ist nicht zwigend erforderlich oda ?
doch. für
a=b=c;
typ* temparray; //keine variablen leer stehen lassen
und mach dazu noch ein StaticArray, das nicht wachsen kann und nicht new benutzt.
-
volkard schrieb:
template<class typ,int size> class MyArray {
warum ist size ein template-argument? kannst doch beruhigt die initial size auf 64 festegen oder als konstruktorargument nehmen. vorteil: nicht jedes array braucht eigenen code und die exe wird kleiner, das programm am ende scneller.
Stimmt. Hast vollkommen recht
Das dann für jedes Array nen eigener Code erzeugt wird, daran hab ich nicht gedacht...volkard schrieb:
MyArray(); MyArray(const MyArray &Array_kopie); MyArray(typ* arr); typ operator=(const MyArray& a); typ &operator[] (unsigned int i); const typ &operator[](unsigned int i) const; ~MyArray() { delete [] array; }
besser, man macht konstruktoren, zuweisungsop und dtor zusammen.
Sind doch !!??
Oder meinste alle auf einen Haufen.
volkard schrieb:
MyArray(); MyArray(typ* arr); MyArray(const MyArray &Array_kopie); typ operator=(const MyArray& a); ~MyArray() { delete [] array; } typ &operator[] (unsigned int i); const typ &operator[](unsigned int i) const;
und der rückgabetyp des op= ist gelinde gesagt gewagt.
O man. Upps soll natürlich MyArray heißen...
volkard schrieb:
leider muss das umgeschrieben werden zu
template<class typ,int size> MyArray<typ,size>::MyArray() :array(new typ[size])//das hier wichtig für wenn exceptions ,aktSize(size) { }
Von dem Code verstehe ich nur Bahnhooof
volkard schrieb:
naja, wollen wir nicht doch lieber begin und end übergeben? so isses ein wenig komisch.
Ok OK
volkard schrieb:
template <class typ,int size> const typ &MyArray<typ,size>::operator[](unsigned int i) const { if(i<aktSize) return array[i]; else throw out_of_range("Out of Range !!!"); }
was soll das denn? das widerstebt mir. irgendwas ist da ganz komisch.
Habe ich nen Reh umgefahren ??? Was ist daran komisch
volkard schrieb:
typ* temparray; //keine variablen leer stehen lassen
Wie wo was ???? Was ist den daran Leer
volkard schrieb:
und mach dazu noch ein StaticArray, das nicht wachsen kann und nicht new benutzt.
Meinst du noch ne Template-Klasse mit normalen Arrays ?
-
genau, ne template klasse mit normalen arrays. dann hat wenigsten der template parameter "size" einen sinn
-
Was bringt mir dann diese Klasse. Was soll ich denn da bei einem Arrayüberlauf machen? --> Nichts einfach so lassen oder ???
-
Freak_Coder schrieb:
Was bringt mir dann diese Klasse. Was soll ich denn da bei einem Arrayüberlauf machen? --> Nichts einfach so lassen oder ???
assert //ziemlich gut
oder
__asm int 3 //lustig, doch hilfreich
oder
throw //pass nicht zum c++-stiloder ganz perfekt ein eigenes ASSERT, was erst asm int 3 macht (aber nur wenn ein debugger mitläuft) und dann throw (ne eigene exception-klasse mit __LINE__ und __FILE__ übergeben).
ach, mach erstmal einfach assert. indexgrenzenüberschreitungen sind halt so häufige fehler und mit ner eigenen array-klasse so einfach wegzumachen, daß man eigenlich immer ne eigene klasse nehmen sollte.
-
Ok! Weiß zwar noch nicht über asserts aber kann mir ja das Wissen aneignen
Wäre mal gut wenn du mal auf Seite 4 schauen würdest da habe ich dir noch ne Menge fragen gestellt(letzer Beitrag(Die assert frage hat sich dann wohl da geklärt))...
-
Freak_Coder schrieb:
Wäre mal gut wenn du mal auf Seite 4 schauen würdest da habe ich dir noch ne Menge fragen gestellt(letzer Beitrag...
dachte, alles sei geklärt.
mit leer meinte ich uninitialisiert. siehe http://www.volkard.de/Cpp/Tutorial/Grundlagen/Variablen/index.html
und ja, ich meine eine array-klasse um ein normales array. der wunsch müßte auf seite 1 schon stehen.
template<class typ,int size> class MyArray { typ array[size]; public: typ &operator[] (unsigned int i); const typ &operator[](unsigned int i) const; };
und in die op[] fein assert oder irgendwas rein.
-
Wenn ich das richtig gesehen habe gibt der op= immer noch ne Kopie zurück und ist damit noch etwa doppel so langsam wie er sein müßte.
-
Habe jetzt meine Klasse wieder umgeändert, nur gibt es etwas was ich noch nicht verstehe:
template<class typ,int size> MyArray<typ,size>::MyArray() :array(new typ[size])// Mit dieser schreibweise ruft man doch ander Ctors auf oda ,aktSize(size) // aber was hat array() und aktSize() da zu suchen (nichts kapisch) { }
Einer ne Erklärung vielleicht oder nen Link ???
-
Freak_Coder schrieb:
Einer ne Erklärung vielleicht oder nen Link ???
weder noch. ich hab da gelogen. deine version ist hübscher.
-
Häää, wenn das so ist !
Aber gibt es diese Schreibweise wirklich oder auch gelögen oda ???Und was war damit:
volkard schrieb:
template <class typ,int size> const typ &MyArray<typ,size>::operator[](unsigned int i) const { if(i<aktSize) return array[i]; else throw out_of_range("Out of Range !!!"); }
was soll das denn? das widerstebt mir. irgendwas ist da ganz komisch.
Ist da auch was gelogen oder? Caipi meinte ich solls so machen ?
-
Freak_Coder schrieb:
Häää, wenn das so ist !
Aber gibt es diese Schreibweise wirklich oder auch gelögen oda ???die gibt es. und irgendwann wird sie besser als die jetzige. im moment ist die jetzige besser weil übersichtlicher.
Und was war damit:
volkard schrieb:
was soll das denn? das widerstebt mir. irgendwas ist da ganz komisch.
Ist da auch was gelogen oder? Caipi meinte ich solls so machen ?
das widerstebt mir wirklich. irgendwas ist da wirklich ganz komisch.
das klint so, als wolle man programmierfehler zur laufzeit fangen und heilen.
-
Weil ich irgendwie nicht verstehe was du meinst werde ich es einfach mal rausnemen und nur ein return (vorerst) reinsetzten.
-
Hier nun nochmal alles:
template<class typ> class MyArray { typ* array; int aktSize; void grow(size_t newSize); public: MyArray(size_t size); MyArray(const MyArray &Array_kopie); MyArray(size_t size,typ* arr_anfang,typ* arr_ende); MyArray &operator=(const MyArray& a); typ &operator[] (unsigned int i); const typ &operator[](unsigned int i) const; ~MyArray() { delete [] array; } }; template<class typ> MyArray<typ>::MyArray(size_t size) { aktSize=size; array=new typ[size]; } template<class typ> MyArray<typ>::MyArray(const MyArray &Array_kopie) { array=new typ[Array_kopie.aktSize]; aktSize=Array_kopie.aktSize; for(int i=0;i<Array_kopie.aktSize;i++) array[i]=Array_kopie.array[i]; } template<class typ> MyArray<typ>::MyArray(size_t size,typ* arr_anfang, typ* arr_ende) { aktSize=size; array=new typ[size]; for(int i=0;&(arr_anfang[i])!=arr_ende;i++) array[i]=arr_anfang[i]; } template <class typ> typ &MyArray<typ>::operator[](unsigned int i) { if(i>aktSize) grow(i); return array[i]; } template <class typ> const typ &MyArray<typ>::operator[](unsigned int i) const { return array[i]; } template <class typ> MyArray<typ> &MyArray<typ>::operator=(const MyArray& a ) { if(aktSize<a.aktSize) { delete [] array; array=new typ[a.aktSize]; } MyArray temp(a); std::swap(array,temp.array); std::swap(aktSize,temp.aktSize); return *this; } template <class typ> void MyArray<typ>::grow(size_t newSize) { int altSize=aktSize; aktSize=newSize * 2; typ* temparray=new typ [aktSize]; for(int i=0;i<altSize;i++) temparray[i]=array[i]; delete [] array; array=temparray; } //---------------------------------------------------------------------------- template <class typ,size_t size> class StaticArray { typ array[size]; public: StaticArray() { } StaticArray(typ* arr_anfang,typ* arr_ende); typ &operator[] (unsigned int i); const typ &operator[](unsigned int i) const; }; template<class typ,size_t size> StaticArray<typ,size>::StaticArray(typ* arr_anfang, typ* arr_ende) { for(int i=0;&(arr_anfang[i])!=arr_ende;i++) array[i]=arr_anfang[i]; } template <class typ,size_t size> typ &StaticArray<typ,size>::operator[](unsigned int i) { assert(i<size); return array[i]; } template <class typ,size_t size> const typ &StaticArray<typ,size>::operator[](unsigned int i) const { assert(i<size); return array[i]; }
In was für einen Datei speichert man am besten nun so was ab um nachher damit in eigenen Programmen arbeiten zu können.
Und sonst alles diesmal in ORDNUNG ....
-
das ganze kommt am besten in einen eigenen header, also eine *.hpp