Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » dynamisches Array

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
20.12.2004, 14:13 Uhr
Mutabor



Hallo Forum
Ich habe mir ein zweidimensionales, dynamisches Array gebastelt.
Wer sieht hier noch Verbesserungsmöglichkeiten?
Danke in voraus.


C++:
#ifndef _multi_dim_array8_h
#define _multi_dim_array8_h
#include<iostream.h>
#include<stdlib.h>
#include<assert.h>
// class D1
template <class T> class D1
{
     T *Data;
     public :
     int delta;
     int s1,z1; //Dimensionsgröße
     //Konstruktor
     D1(int,int);    //letzte Argument ist delta
     ~D1();
T Data_delete();
     //Methoden
T Getarray(int);
T Getarray1(int);
void Setarray(T,int);
void Setarray1(T,int);
void D1_aendernplus(int,int);
void D1_aendernplus1(int,int);
int Dimsize(int);
void Deletearray();
};
// class D2
template <class T> class D2
{
     public :
     int delta;
     int s1,s2; //Dimensionsgrößen
     int z1,z2; //Dimensionszwischengrößen
     D1< D1<T>* > *Data;
     //Konstruktor
     D2(int,int,int);  //letzte Argument ist delta
     ~D2();
     //Methoden
T Getarray(int,int);
T Getarray1(int,int);
void Setarray(T,int,int);
void Setarray1(T,int,int);
void D_aendernplus(int,int);
int Dimsize(int);
void Deletearray();
};

// class D1
template <class T>
D1<T>::D1(int d1=0,int del=0)
{
        int i;
        delta = del;
        if(d1<=0)d1 =1;
        s1 = d1;
        Data = new  T [d1];
        assert(Data != NULL);//assert_Meldung   Speicherfehler
        for( i = 0; i < d1; i++)
            Data[i] = (T) 0;
}
template <class T>
D1<T>::~D1()
{
     delete [] Data;
}
//Funktion löscht alte Array und legt neues Array mit Dimsize 1 an
template <class T>
void D1<T>::Deletearray()
{
    T *Temp;
    Temp = new  T [1];
    assert(Temp != NULL);//assert_Meldung   Speicherfehler
    Temp[0] = (T) 0;
    delete [] Data;
    Data = Temp;
    s1 = 1;
}
template <class T>
D1<T>::Data_delete()
{
      delete [] Data;
      return 0;
}
template <class T>
T D1<T>::Getarray(int d)
{
      assert(d >= 0);//assert_Meldung wenn der Index kleiner als 0 ist
      assert(d < s1);//assert_Meldung wenn der Index größer als die Dimensionsgröße ist
         return Data[d];
}
template <class T>
T D1<T>::Getarray1(int d)
{
      return Data[d];
}
template <class T>
void D1<T>::Setarray1(T daten,int d1)
{
    Data[d1] = daten;
}
template <class T>
void D1<T>::Setarray(T daten,int d1)
{
      if(d1 >= s1){
        z1 = s1;
        D1_aendernplus(d1,z1);
      }
      Data[d1] = daten;
}
template <class T>
void D1<T>::D1_aendernplus(int d1=0,int d1alt = 0)
{
     T *Temp;
     int j,k;
        if(d1 >= s1){
          if(d1 - s1 >= delta)
             s1 = d1+1;  //erweitert Array Data um d1
          else
             s1 = s1 + delta;  //erweitert Array Data um delta
        }
        Temp = new  T [s1];
        assert(Temp != NULL);//assert_Meldung   Speicherfehler
        for( k = 0; k < s1; k++)
             Temp[k] = (T) 0;
        for(j = 0;j < d1alt; j++)
          Temp[j] = Data[j];
        delete [] Data;
        Data = Temp;
}
template <class T>
void D1<T>::D1_aendernplus1(int d1=0,int d1alt = 0)
{
     T *Temp;
     int j,k;
     d1++; //D1 gibt Position an, neue Größe D1 + 1
        Temp = new  T [d1];
        assert(Temp != NULL);//assert_Meldung   Speicherfehler
        for( k = 0; k < d1; k++)
            Temp[k] = (T) 0;
        for(j = 0;j < d1alt; j++)
          Temp[j] = Data[j];
        delete [] Data;
        Data = Temp;
}
//Funktion gibt die Dimensionsgröße aus
template <class T>
int D1<T>::Dimsize(int si=0)
{
     int siz = 0;
     switch(si){
        case 1 :{ siz = s1;break;}
     }
     return siz;
}
// class D2
template <class T>
D2<T>::D2(int d1=0,int d2=0,int del=0)
{
        int i;
        delta = del;
        int dummy = 0;
        if(d1<=0)d1 =1;
        if(d2<=0)d2 =1;
        s1 = d1;
        s2 = d2;
        Data = new D1< D1<T>* >(d1,dummy);    //0 = Dummy für delta
        for(i = 0; i < d1; i++)
          Data->Setarray1(new D1<T>(d2,dummy),i);
}
template <class T>
D2<T>::~D2()
{
    int i;
    for(i = 0; i < s1; i++)
    Data->Getarray1(i)->Data_delete();
}
//Funktion löscht alte Array und legt neues Array mit Dimsize 1 an
template <class T>
void D2<T>::Deletearray()
{
    int i;
    for(i = 0; i < s1; i++){
        Data->Getarray1(i)->Deletearray();  //////////////
    }
    s1 = 1;
    s2 = 1;
}
template <class T>
void D2<T>::D_aendernplus(int d1=0,int d2=0)
{
        int i;
        int dummy = 0;
        z1 = s1;
        z2 = s2;
        if(d1 >= s1){
          if(d1 - s1 >= delta)
             s1 = d1+1;  //erweitert Array Data um d1
          else
             s1 = s1 + delta;  //erweitert Array Data um delta
          Data->D1_aendernplus1(s1,z1); //d1
          for(i = z1; i < s1; i++){
          Data->Setarray1(new D1<T>(s2,dummy),i);
        } }
        if(d2 >= s2){
          if(d2 - s2 >= delta)
             s2 = d2+1;  //erweitert Array Data um d2
          else
             s2 = s2 + delta;  //erweitert Array Data um delta
          for(i = 0; i < s1; i++){
            Data->Getarray1(i)->D1_aendernplus1(s2,z2);  //////////////
        }}
}
template <class T>
T D2<T>::Getarray(int d1,int d2)
{
      assert(d1 >= 0);//assert_Meldung wenn der Index kleiner als 0 ist
      assert(d2 >= 0);
      assert(d1 < s1);//assert_Meldung wenn der Index größer als die Dimensionsgröße ist
      assert(d2 < s2);
      return Data->Getarray1(d1)->Getarray1(d2);
}
template <class T>
T D2<T>::Getarray1(int d1,int d2)
{
      return Data->Getarray1(d1)->Getarray1(d2);
}
template <class T>
void D2<T>::Setarray(T daten,int d1,int d2)
{
      if(d1 < 0 || d2 < 0){
        D_aendernminus(d1,d2);
      }
      if(d1 >= s1 || d2 >= s2){
        D_aendernplus(d1,d2);
      }
        Data->Getarray1(d1)->Setarray1(daten,d2);
}
template <class T>
void D2<T>::Setarray1(T daten,int d1,int d2)
{
        Data->Getarray1(d1)->Setarray1(daten,d2);
}
//Funktion gibt die Dimensionsgröße aus
template <class T>
int D2<T>::Dimsize(int si=0)
{
     int siz = 0;
     switch(si){
        case 1 :{ siz = s1;break;}
        case 2 :{ siz = s2;break;}
     }
     return siz;
}
#endif



Bearbeitung:
Codetags eingefügt

Dieser Post wurde am 20.12.2004 um 14:39 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
20.12.2004, 21:39 Uhr
(un)wissender
Niveauwart


Wow, was ist denn das?!
Die einzig Verbesserungsmöglichkeit, die ich sehe, ist das Teil neu zu schreiben, sorry, hart aber herzlich.
Was soll das überhaupt machen?
Außerdem bietet sich da immer noch std::vector<std::vector<T> > an...

1.Schreibe vernünftige Methodennamen
Bsp.: D_aendernplus, was soll das sein? Methodennamen müssen selbsterklärend sein.

2. Natürliche Syntax
soll das hier
T Getarray(int,int);
T Getarray1(int,int);
void Setarray(T,int,int);
void Setarray1(T,int,int);

etwa (operator[])[] oder operator()
darstellen?

3. Mach erstmal 1 und 2, dann kommt 3...N
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
21.12.2004, 08:58 Uhr
virtual
Sexiest Bit alive
(Operator)


Hallo Mutabor.
Ich gehe mal einfach davon aus, daß Du sowas wie ein Array unbedingt selbst schreiben willst, obwohl es das schon gibt, zB in Form von std::vector oder aber std::valarray.

Okay, schauen wir uns aber erstmal D1 an:
Zunächst solltest Du Methodennamen wählen, die nachvollziehbar sind. "D1_aendernplus" ist zB ein schlechter Name: Ich habe erstmal den Source lesen müssen, um zu wissen, daß Du einfach das Array vergößern/verändern möchtest. Einen Namen wie zB "setSize" hätte ich hier um einiges besser gefunden; denn dann wärer anhand des Namens wohl jedem klar: das Ding verändert die Größe. Analoges gilt für die Methoden "set/getArray": Damit setzt oder holst Du kein Array, sondern ein Arrayelement; also hätte ich hier einen Namen wie "set/getItem" oder einfach "set/get" passender gefunden (letzters deshalb, weil Zugriff auf die Elemente die Hauptoperation ist, die man mit Arrays macht und daher einen kurzen Namen rechtfertigen).
Namen sind recht wichtig und nicht nur für mich ein Qualitätmerkmal.

Funktional stellt Dein D1 eine Untermenge der Funktionalität bereit, die std::vector breitstellt. Solltest Du die Klasse geschrieben haben, weil Du std::vector nicht kanntest, so empfehle ich dir std::vector zu nutzen. Solltest Du unbedingt selbst die ArrayKlasse schreiben wollen, so würde ich sie ungefähr auf folgendes Reduzieren:

C++:
template<typename T>
class D1 {
// Attribute
private:
     T* data;  // Elemente
     unsigned size;  // Anzahl Elemente

public:
     // Früher setArray()
     T& at(unsigned i) {
          if (i>=size) throw std::runtime_error("D1::at: index out of bounds");
          return data[i];
     }
     // Früher getArray()
     const T& at(unsigned i) const {
          if (i>=size) throw std::runtime_error("D1::at: index out of bounds");
          return data[i];
     }
     // Früher setArray1()
     T& operator [] (unsigned i) {
          return data[i];
     }
     // Früher getArray1()
     const T& operator [] (unsigned i) const {
          return data[i];
     }
     // Größe ändern
     void setSize(unsigned n) {
          if (n>0) {
              T* tmp = new t[n];
              for(unsigned i=0; i<n && i<size; ++i) tmp[i] = data[i];
              size = n;
              delete[] data;
              data = tmp;
          }
          else {
              delete[] data;
              data = NULL;
              size = 0;
          }
     }
};


Fehlern noch ein paar Methoden, aber ich denke, die Richtung ist mal skizziert. Ein D2 als allg. Klasse würde ich überhaupt nicht definieren, weil man hier einfach ein typdef machen kann:

C++:
typedef D1< D1<int> > D2_for_int;


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.12.2004, 14:10 Uhr
Mutabor



Hallo Leute
Das mit den Methodennamen ist so eine Sache.
Ich schätze, dass Ihr am Anfang eurer Programmierlaufbahn, auch nicht so recht wusstet
was für Namen aussagekräftig sind.
Es kann ja mal Jemand eine Liste für aussagekräftige Methodennamen erstellen.

Liegt schon eine Weile zurück als ich die Klassen geschrieben habe.
Es ist ja gut das man fertige Arbeit in seinen Programmen nutzt, aber man sollte auch
wissen wie man etwas von Hand machen kann.
Jeder Anfänger hat nun mal nicht das Wissen das Ihr als Profi habt.
Bitte deshalb um Nachsicht, im Namen aller Anfänger.

In diesem Sinne frohe Weihnachten.

Gruß Mutabor
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: