Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Wie setze ich das dort hin ?

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 ] > 2 < [ 3 ]
010
23.04.2006, 10:00 Uhr
Spacelord
Hoffnungsloser Fall


Hi Helmut,
wenn du dir meinen Konstruktor oben genau anschaust wirst du feststellen dass bei dieser Auslegung die Grösse des Zeigerarrays bei der Konstruktion dynamisch festlegbar ist(was zweifelsohne erstmal ein Vorteil ist).
Wenn das generell nicht erwünscht ist,dann ist deine Lösung natürlich klar vorzuziehen.
Als Übung ist die dynamische Geschichte aber wesentlich interessanter weil im weiteren Verlauf der Implementierung interessante,in der C++ Welt immer wieder auftauchende,Probleme entstehen.
Hier ist mal ne kleine(durchaus problembehaftete) Implementierung um einige Probleme und auftauchende Fragen zu verdeutlichen:

C++:
#include <iostream>
using namespace std;

class CLebewesen
{
    public:
        virtual void out(){cout<<"base"<<endl;}
        ~CLebewesen(){};
};

class CMensch : public CLebewesen
{
    public:
        virtual void out(){cout<<"Mensch"<<endl;}
};

class CTier : public CLebewesen
{
    public:
        virtual void out(){cout<<"Tier"<<endl;}
};

class CFeld
{
    private:
        size_t max_size;
        CLebewesen **pWesen;
    public:
        CFeld(size_t m_):max_size(m_)
        {  
            pWesen = new CLebewesen*[max_size];
            for(size_t idx=0;idx<max_size;++idx)
                pWesen[idx]=NULL;
        }
        ~CFeld()
        {
            for(size_t idx=0;idx<max_size;++idx)
                delete pWesen[idx];
            delete pWesen;
        }
      
        void mSetLebewesen(size_t index, CLebewesen* pEinWesen)
        {
            if(index< max_size)
              pWesen[index]= pEinWesen;
            else
                cout<<"ungueltiger Index"<<endl;
        }
        CLebewesen* getAt(size_t idx)
        {
            if(idx< max_size)
                return pWesen[idx];
            else
                return NULL;
        }
        size_t size(){return max_size;}
};

int main()
{
    CFeld feld(10);
    feld.mSetLebewesen(6,new CTier());
    feld.mSetLebewesen(1,new CMensch());
    CLebewesen* w = feld.getAt(6);
    w->out();
        //oder
    feld.getAt(1)->out();

    return 0;
}


In dieser Lösung habe ich mich dafür entschieden dass CFeld bei seiner Zerstörung die Lebewesenobjekte hinter den Zeigern löscht.
Auf den ersten Blick sehr komfortabel....
Aber was passiert wenn z.B. ne Funktion wie diese

C++:
void boooom(CFeld f)//Übergabe per Wert
{
    size_t s = f.size();
    for(size_t idx=0;idx<s;++idx)
    {
        if(f.getAt(idx) != NULL)
            f.getAt(idx)->out();
    }
}

.....
int main()
{
    CFeld feld(10);
    feld.mSetLebewesen(6,new CTier());
    feld.mSetLebewesen(1,new CMensch());
    boooom(feld);
    feld.getAt(1)->out();//auf Wiedersehen

    return 0;
}



aufgerufen wird?
-Wie kann man das Problem vermeiden,ausser darauf zu hoffen dass der Benutzer der Klasse nur Funktionen etc. schreibt bei denen die CFeld Objekte per Referenz oder Pointer übergeben werden?
-Wie hat ein Copy Konstruktor auszusehen?
-Was ist zu tun wenn das Array in CFeld nachträglich wachsen soll?
-Wie soll sich CFeld bei einer Zuweisung(eines eventuell grösseren CFeldes) verhalten?
usw. usw.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.

Dieser Post wurde am 23.04.2006 um 10:01 Uhr von Spacelord editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
23.04.2006, 13:43 Uhr
cmos



Hallo und viele Dank für eure Hilfe.
Mit Zeiger auf Zeiger funktioniert das jetzt.
Noch eine Frage zum Schluss.
Wenn ich

C++:
CLebewesen* pWesen = new CLebewesen[5]


schreibe, habe ich doch dynamisch ein Array von 5 Elementen des
Typs CLebewesen erzeugt.
Ein Array wird ja intern auch wie ein Zeiger behandelt, wurde hier geschrieben.
Deshalb verstehe ich nicht ganz warum das mit oben geschriebenem CLebewesen[5]
nicht funktioniert. pWesen ist doch ein Zeiger auf 5 Elemente des Typs CLebewesen,
also müsste ich doch pWesen[index]=pEinWesen zuweisen könne,...rein theoretisch.
Eine Klammer erstzt einen Stern, sage ich jetzt pauschal.
Wenn ich

C++:
pWesen[index]=*pEinWesen


schreibe und CLebewesen mit CLebewesen* pWesen = new CLebewesen[5] erzeugt wurde
bekomme ich keine Compilerfehler. Bin mir dann aber nicht sicher ob er auch das Lebewesen
in den Array ablegt.

Wenn man beispielsweise

C++:
int *p = new int[10];
int a = 5;
int *pa = & a;
p[2] = *pa;


schreibt, hat das Feld 2 den Wert 5 und dieser ist dort abgspeichert.
Wenn man das mit pWesen macht, was ist dann im Array von CLebewesen[5] gespeichert
bzw. was wird ins Array CLebewesen[5] gespeichert wenn ich es, wie vorgeschlagen,
mit Zeiger auf Zeiger erstelle ? Wird dann nur die Adresse meines z.B. erzeugten Menschen
in diesem Array gespeichert oder wird das gesamte Objekt in diesen Array kopiert ?

Grüße,
cmos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
23.04.2006, 15:08 Uhr
(un)wissender
Niveauwart


Ihr müsst mal auf mem leaks aufpassen.


C++:
void mSetLebewesen(size_t index, CLebewesen* pEinWesen)
        {
            if(index< max_size)
              pWesen[index]= pEinWesen;
            else
                cout<<"ungueltiger Index"<<endl;
        }



Sehr gefährlich. pWesen[index] muss vorher gelöscht werden.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
23.04.2006, 15:17 Uhr
Lensflare




Zitat von cmos:

Ein Array wird ja intern auch wie ein Zeiger behandelt, wurde hier geschrieben.
Deshalb verstehe ich nicht ganz warum das mit oben geschriebenem CLebewesen[5]
nicht funktioniert. pWesen ist doch ein Zeiger auf 5 Elemente des Typs CLebewesen,
also müsste ich doch pWesen[index]=pEinWesen zuweisen könne,...rein theoretisch.
Eine Klammer erstzt einen Stern, sage ich jetzt pauschal.



Indem du einen * benutzt, hast du einen Zeiger oder ein Array.
Im Fall von pWesen benutzt du es als Array.
Deswegen muss das Array wiederum ein Zeiger sein. Es sind also zwei * nötig.
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
23.04.2006, 19:36 Uhr
Spacelord
Hoffnungsloser Fall



Zitat von (un)wissender:
Ihr müsst mal auf mem leaks aufpassen.


C++:
void mSetLebewesen(size_t index, CLebewesen* pEinWesen)
        {
            if(index< max_size)
              pWesen[index]= pEinWesen;
            else
                cout<<"ungueltiger Index"<<endl;
        }



Sehr gefährlich. pWesen[index] muss vorher gelöscht werden.



Zitat von Spacelord:

Hier ist mal ne kleine(durchaus problembehaftete) Implementierung ......


Dessen bin ich mir bewusst.Es war auch nicht mein Anliegen ne "perfekte" Lösung zu liefern sondern zum Nachdenken über genau solche Probleme anzuregen.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
24.04.2006, 07:51 Uhr
(un)wissender
Niveauwart


Na ja, besser gleich richtig machen. Sowas sehen Anfänger eh nicht. Und (Pseudo-)Profis öfter mal auch nicht;(.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
24.04.2006, 08:30 Uhr
Spacelord
Hoffnungsloser Fall



Zitat von (un)wissender:
Na ja, besser gleich richtig machen.


Dann ist es keine Übung mehr...

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
24.04.2006, 12:06 Uhr
(un)wissender
Niveauwart


Sowas ist keine Übung meiner Meinung nach. Da kommen Anfänger einfach nicht drauf, vor allem nicht, wenn es ihnen falsch vorgemacht worden ist. Und der Code ist falsch. Übungscode muss sicherlich nicht vollständig sein, dafür muss aber das, was gezeigt wird, korrekt sein. Ansonsten ist ein Hinweis notwendig. Na ja, nimm das nicht persönlich, aber ich sehe vergleichbares in letzter Zeit so oft und muss mit dem Zeug arbeiten...
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
018
24.04.2006, 12:27 Uhr
Spacelord
Hoffnungsloser Fall


Der Code ist nicht idiotensicher,aber nicht falsch.

Falscher Code und deine Erwartungshaltung wie die Klasse zu benutzen sein sollte sind 2 verschiedene Sachen.
Ist std::auto_ptr falsch weil die Klasse großes Potential für Fehllbenutzungen bietet?

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
019
24.04.2006, 13:54 Uhr
ao

(Operator)



Zitat von (un)wissender:
Übungscode muss sicherlich nicht vollständig sein, dafür muss aber das, was gezeigt wird, korrekt sein.


Bitte nicht vergessen, dass das hier ein offenes Forum ist und kein Helpdesk. Die Leute, die hier Fragen beantworten, tun das freiwillig, ohne Lohn und in der Zeit, die sie erübrigen können. Die Antworten, die hier gegeben werden, sind spätestens nach ein paar Iterationen meistens ziemlich gut, weil mehrere Leute drübergucken und mitdenken, und ich meine, wenn ein Frager die Bereitschaft mitbringt, die angebotenen Lösungen selber nachzuvollziehen, ist er damit gut bedient.

Leute, die eine Kann-ich-das-blind-kopieren-Lösung wollen, sollten sich dagegen besser an einen Professionellen wenden, der ihnen für 25 (cand. ing.) bis 100 (promovierter Senior Software Consulter) Euro pro Stunde weiterhilft.

Außerdem ist Speicherverwaltung eins der komplizierteren Themen in C++, und wer sich als Anfänger damit anlegt, der sollte wissen, dass vielleicht das eine oder andere Problem auf ihn zukommt.

Gruß,
ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 < [ 3 ]     [ 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: