Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Klassenobjekte während d. Laufzeit belibig oft erzeugen

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 ]
000
30.03.2004, 21:32 Uhr
~RIP
Gast


Hi!

Ich kenne mich mit dynamischer Speicherreservierung nicht so gut aus - ich weiß nicht mal ob das überhaupt funktioniert was ich wor habe:

Nehmen wir mal an ich will während der Laufzeit 4 Objekte der Klasse Scroller erzeugen (diese Fkt. erfüllt der code ja schon). Später möchte möglicher Weise noch eines dieser Objekte löschen oder noch ein neues hinzufügen? Geht das überhaupt? (*Wahn-Schrei!!!*)

Dummer Weise bleibe ich schon an einer Konstante hängen ...


C++:
    class Scroller
    {
        private:
            int x;
            int y;
            int values;
            float size;
        public:
            Scroller(int _x, int _y, int _values, float _size)
            {
                x=_x;
                y=_y;
                values=_values;
                size=_size;
            }
            ~Scroller()
            {
            }
            int X()            {return x;}
            int Y()            {return y;}
            int Values()    {return values;}
            float Size()    {return size;}
    };

    const ScrAnzahl=4; // hmm? eine Konstante - geht aber nett anders! oder?
    Scroller *Scrollers[ScrAnzahl]; // ... den hier kann man nur Konstanten benutzen
    for (loop=0;loop<ScrAnzahl;loop++)
    {
        Scrollers[loop] = new Scroller(loop,loop,255,1.0f);

        printf("%i",Scrollers[loop]->X());    // test
    }

    delete *Scrollers;

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
30.03.2004, 21:52 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

Geht das überhaupt? (*Wahn-Schrei!!!*)


die antwort ist, nein geht so ohne weiteres nicht...
die einfach lösung ist nicht von hand zu allokieren und z.b. einen std::vector zu verwenden...

dein
C++:
delete *Scrollers;
gibt nicht den kompletten von dir allokierten speicher frei sondern nur den auf den der erste pointer in deinem array zeigt... du musst da schon auch noch die schleife durchlaufen lassen und jeden einzeln allokierten auch wieder einzeln freigeben


die ätzende lösung ist in etwa so

C++:
Scroller **scArray,**tmp;
int i,anzahl=4711;
scArray=new Scroller*[anzahl];
for(i=0;i<anzahl;++i)scArray[i]=new Scroller(.....);

//so wenn du jetzt feststellst das du die arraygrösse ändern willst kannst du das wie folgt machen...
//angenommen du willst speicher für 3 scroller mehr haben...
tmp=new Scroller*[anzahl+3];
for(i=0;i<anzahl;++i)tmp[i]=scArray[i];  //kopieren der alten zeiger...
delete [] scArray; //alten speicher freigeben
scArray=tmp;  //scArray zeigt auf den neuen speicher

for(i=anzahl;i<anzahl+3;++i)scArray[i]= new Scroller(......); //die drei neuen objekte einfügen...
anzahl+=3;

//am ende das freigeben nicht vergessen
for(i=0;i<anzahl;++i)delete scArray[i];
delete [] scArray;





Bearbeitung:

die ätzende lösung schreit förmlich danach in ner klasse gekapselt zu werden um das ganze noch handlebar und wenig fehleranfällig zu machen


--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 30.03.2004 um 22:00 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
31.03.2004, 10:05 Uhr
RHBaum



Dein Problem ist ... du legst dein Array aufn Stack an ...
Das bedeutet, um den Speicherbereich aufm Stack korreckt anlegen zu koennen, musst du die groesse vorher schon kennen ... also sprich zur compilezeit.
Fuer alles andere geht es nur dynamisch !

Leg dein Array dynamisch an, und es funzt ....



C++:
   typedef Scroller * LPScroller; // ok, haessliche M$ Synthax :-)
   ScrAnzahl=4; // mal als nicht konstante :-)
   LPScroller * Scrollers = new LPScroller[ScrAnzahl]; // ... nu isses dynamisch
    for (loop=0;loop<ScrAnzahl;loop++)
    {
        Scrollers[loop] = new Scroller(loop,loop,255,1.0f);

        printf("%i",Scrollers[loop]->X());    // test
    }
    // Alle Objecte loeschen
    for (loop=0;loop<ScrAnzahl;loop++)
    {
        delete Scrollers[loop];
        Scrollers[loop] = NULL; // Unnoetig, aber paranoia is cool :-)
    }

    delete[] Scrollers; // nur dein Array of Pointer weg ... nich die Objecte .... die ham ma vorher schon geloescht




Aber Prinzipiell .....
Hoer auf Windalf ! :p
Brauchst du die Scroller unbedingt anderswo als Zeiger ? Wenn nicht, dann spendir denen ein CCTor und nen Zuweisungs Op .... und benutzt die Teile mit "normalen" containern .... Das sieht besser aus und ist verstaendlicher zu lesen .

Aber ich nehm an, du probierst grad mit zeiger und speicherverwaltung rum ? :p

Ciao .....

Dieser Post wurde am 31.03.2004 um 10:09 Uhr von RHBaum editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
31.03.2004, 11:22 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

Hoer auf Windalf ! :p


Wie meinst du das RHBaum...Ist da ausser das das nervend ätzend und fehleranfällig ist irgendwie falsch?

bis vor kurzem kannte ich die stl noch gar nicht und hab das wirklich immer von hand so gemacht...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
31.03.2004, 13:39 Uhr
RHBaum



OMG ... totale Missinterpretation :p deutsche Sprache schwere Sprache :p
Weiss nicht mal wie es genau heissen muss ...
"Hoer auf Windalf" , oder "Hoere auf Windalf"
Zumindest meinte ich nicht "Hoer auf ! Windalf"

Er sollte auf dich hoeren ... und ned das du aufhoeren sollst

Ciao ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
31.03.2004, 13:41 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


*rofl*
ach so meinst du das.
darauf wär ich im leben nicht gekommen. Ich dachte du hättest da noch ein schlaues konzept von dem ich da nichts weiss...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
31.03.2004, 18:36 Uhr
~RIP
Gast


WOW!
@Windalf: Programmierst du beruflich? Scheinst dich ja ziemlich gut auszukennen!
Danke für die Hilfe!
(:danke

Der Code kann jetzt alles machen - so wie ich es brauche ...

Wäre nett wenn ihr euch das noch mal anschaut ... für mich ist das wie gesagt alles ziemlich neu mit dieser Speicherreservierung ...
Da sind bestimmt noch ein paar uneffektive Sachen oder sogar kleine Fehler drin ... funktionieren tut es bei mir aber


C++:
// Header: "Classes.h"
class Scroller
{
    private:
        int x;
        int y;
        int values;
        float size;
        char * name;
    public:
        Scroller(int _x, int _y, int _values, float _size, char *_name)
        {
            x=_x;
            y=_y;
            values=_values;
            size=_size;
            name=new char[strlen(_name)+1];
            strcpy(name,_name);
        }
        ~Scroller()
        {
            delete []name;
        }
        int X()            {return x;}
        int Y()            {return y;}
        int Values()    {return values;}
        float Size()    {return size;}
        char* Name()    {return name;}
};

// Eine Klasse zum Verwalten von Scrollerobjekten
class ScrObj
{
    private:
        Scroller **scArray,**tmp;
        int Scramount;    // Anzahl der Scroller / Größe von scArray
        int loop;        // hmm - das ist bestimmt der Schalter für den Rasenmäher! :)
    public:

        ScrObj(int Anzahl)    // Konstruktor [Anzahl == Arraygröße]
        {
            Scramount=Anzahl;
            scArray=new Scroller*[Scramount];
            for (loop=0;loop<Scramount;loop++)
            {
                // neue Scrollerobjekte mit Standardwerten erzeugen
                scArray[loop]=new Scroller(0,0,0,0.0f,"Scroller");
            }
        }
        ~ScrObj()            // Destruktor
        {
            for(loop=0;loop<Scramount;++loop)
                delete scArray[ loop ];
            delete [] scArray;
        }

        void ChangeScrValues(int Scrnr,int x,int y, int values, float size, char *name)
        {
            scArray[Scrnr]=new Scroller(x,y,values,size,name);
        }

        void AddScr(int x,int y, int values, float size, char *name)    // 1 Scroller hinzufügen
        {
            tmp=new Scroller*[Scramount+1];
            for(loop=0;loop<Scramount;++loop)
                tmp[loop]=scArray[loop];            //kopieren der alten zeiger ...
            delete [] scArray;                        //alten speicher freigeben
            scArray=tmp;                            //scArray zeigt auf den neuen speicher

            scArray[Scramount]= new Scroller(x,y,values,size,name); //neues objekt einfügen ...
            Scramount++;
        }

        void KillScr(int Scrnr)    // 1 bestimmten Scroller entfernen
        {
            // den zu löschenden Scroller mit den Daten des nachfolgenden Scrollers überschreiben
            // alles nach vorne rücken und dann das letzte Array löschen
            for (loop=Scrnr;loop<Scramount-1;loop++)
            {
                scArray[loop]=scArray[loop+1];
            }
            delete scArray[Scramount-1];
            Scramount--;
        }
};


und der Maincode ...

C++:
#include <conio.h>
#include "stdafx.h"
#include "Classes.h"

int main()
{
    ScrObj Scr(2);        // Ein "Scroller-Verwaltungs-Objekt" der Klasse ScrObj erstellen - oder so ähnlich :)

    Scr.ChangeScrValues(0,64,64,255,1.0f,"Testscroller 1");    // Werte eines Scrollers ändern

    Scr.AddScr(64,64,255,1.0f,"Testscroller 3");    // einen neuen Scroller hinzufügen

    Scr.KillScr(0);        // "Testscroller 1" löschen

    //while(1)
    //{
    //}
    return 0;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
31.03.2004, 19:09 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

@Windalf: Programmierst du beruflich? Scheinst dich ja ziemlich gut auszukennen!


äh nein dafür reichts noch nicht..arbeite aber dran...

das ist übel weil du den speicher vorher nicht freigibst... problem ist auch

C++:
void ChangeScrValues(int Scrnr,int x,int y, int values, float size, char *name)
        {
            scArray[Scrnr]=new Scroller(x,y,values,size,name);
        }


wenn du scrnr ne zu hohe nummer mitgibst schmiet der spass ab oder du schreibst in speicher rum der dir nicht gehört...

deshalb eher so

C++:
void ChangeScrValues(int Scrnr,int x,int y, int values, float size, char *name){
if( Scramount<Scrnr)  {    
delete scArray[Scrnr];
scArray[Scrnr]=new Scroller(x,y,values,size,name);
}
}




das hier ist auch noch ein wenig ungeschickt...
also nochmal zum problem, du hast am ende ein array von pointern das ein pointer mehr hat als du eigentlich brauchst...
naja ist eigentlich auch nicht ganz so schlimm, weils ja wenn du neu hinfügst eh neu allokiert wird du büsst dabei höchstens performace ein...
deswegen kann man überlegen ob man nicht immer einfach eine funktion schreibt check_speicher oder sowas... die guckt nach ob genug reserviert ist und wenn nicht reserviert sie gleich x neue plätze... dann kann man x mal einfügen ohne das man ständig neu allokieren muss (wie gesagt das wird programmtechnisch komplizierter aber dafür ist es dann performanter...)
beim löschen ist analog wenn die schere zwischen den zu löschenden und den allokierten pointern zu gross wird auch wieder eine vorher definierte menge x freigeben...
naja und du hast hier noch ein übles fehlerchen drin
du willst ja den scArray[Scrnr] löschen, das kanst du nicht wenn du vorher schon die adresse neu zuweist. der steht dann verloren im speicher... was du da am ende löschst ist ja nicht der den du löschen wolltest sondern das ist der den du nach durchlaufen der schleife ans ende gesetzt hast...

C++:
        void KillScr(int Scrnr)    // 1 bestimmten Scroller entfernen
        {
            // den zu löschenden Scroller mit den Daten des nachfolgenden Scrollers überschreiben
            // alles nach vorne rücken und dann das letzte Array löschen
            for (loop=Scrnr;loop<Scramount-1;loop++)
            {
                scArray[loop]=scArray[loop+1];
            }
            delete scArray[Scramount-1];
            Scramount--;
        }





deshalb mehr so in der art

C++:

        void KillScr(int Scrnr)    // 1 bestimmten Scroller entfernen
        {
            // den zu löschenden Scroller mit den Daten des nachfolgenden Scrollers überschreiben
            delete scArray[Scrnr];

            // alles nach vorne rücken und dann das letzte Array löschen
            for (int loop=Scrnr;loop<Scramount-1;loop++)
            {
                scArray[loop]=scArray[loop+1];
            }
            Scramount--;
        }



--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
31.03.2004, 20:52 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)



Zitat:
Windalf postete
äh nein dafür reichts noch nicht..arbeite aber dran...

rofl was soll denn da nicht reichen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
31.03.2004, 21:04 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@guybrush
mir fehlen noch zuviele grundlagen... du bist ein gutes beispiel dafür... bei jedem dritten thread von dir lern ich noch was richtig neues von dem ich vorher nichts gehört habe...

meine stärke liegt nicht gerade daran api's zu verwenden geschweige denn hinter deren konzepte zusteigen...

was ich glaube ich relativ gut kann ist algorithmen zu bestimmten problemen zu entwickeln was ja aber eigentlich wenig mit programmierung zu tun hat (also quasi z.b. das was navi gerade gefragt hat wie man eine heuristik bastelt um dreiecke kreise und rechtecke zu erkennen würde mich nicht schwer fallen).
Das umsetzen dieser algorithmen in quellcode ist dann ja nicht mehr weiter schwer... ist ja mehr oder weniger nur ein 1:1 abgetippe...
Ich bin also eher auf der Konzeptionellen Ebene vertreten
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 31.03.2004 um 21:05 Uhr von Windalf editiert.
 
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: