Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Freienstein

Frischling

  • »Freienstein« ist der Autor dieses Themas

Beiträge: 84

Wohnort: Berlin

  • Private Nachricht senden

1

29.07.2011, 12:18

Zeiger mit new und delete

Hallo,

im Buch sind ja mehrmals stellen zu sehen, in denen mit einem Pointer und new Instanzen von Klassen auf dem heap erzeugt wurden.

z.B:

C-/C++-Quelltext

1
2
3
4
5
6
7
CSpieler *pSpielerliste = NULL;
pSpielerliste = new CSpieler[Variable];

// oder

CRaumschiff *Schiff;
Schiff = new CMinenleger;


Nun wollte ich fragen ob auch so etwas möglich ist und wenn ja, wie man alles korrekt abrufen kann:

C-/C++-Quelltext

1
2
CKlasse *pZeiger[10];
pZeiger = new CKlasse2[10]


Die beiden Werte in den eckigen Klammern sind rein willkürlich ausgewählt. Die Klasse "CKlasse" ist die Basisklasse, von der die Klasse "CKlasse2" erbt.

Freienstein

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

2

29.07.2011, 13:00

pZeiger ist ein Array aus 10 Zeigern auf Objekte von CKlasse.
Dieses Array befindet sich natürlich auf dem Stack.
Du könntest höchstens jedem Element des Arrays ein Zeiger auf ein (auf dem Heap mittels new erstelltem) Array vom Typ CKlasse2 zuweisen.

Was auch geht ist das hier:

C-/C++-Quelltext

1
2
CKlasse *pZeiger;
pZeiger = new CKlasse2[10]
Signaturen werden überbewertet

Freienstein

Frischling

  • »Freienstein« ist der Autor dieses Themas

Beiträge: 84

Wohnort: Berlin

  • Private Nachricht senden

3

29.07.2011, 13:08

pZeiger ist ein Array aus 10 Zeigern auf Objekte von CKlasse.
Dieses Array befindet sich natürlich auf dem Stack.
Du könntest höchstens jedem Element des Arrays ein Zeiger auf ein (auf dem Heap mittels new erstelltem) Array vom Typ CKlasse2 zuweisen.

Was auch geht ist das hier:

C-/C++-Quelltext

1
2
CKlasse *pZeiger;
pZeiger = new CKlasse2[10]


Schade. Ich bin gerade dabei, mir ein einfaches Strategiespiel zu bauen. Jede einzelne Einheit soll als Instanz auf dem Heap erzeugt werden, da sich die Einheitenwerte nach Kämpfen und sammeln von EXP verändern. Nur müsste ich dann ja den gesamten Speicher für die Einheiten schon am Anfang reservieren ... obwohl ich gar nicht weiß, wie viel Speicher ich überhaupt im Gesamten brauche. Daher habe ich gedacht ich mache das ganze mit dem Zeiger Array und reserviere dann wieder ein Array mehr an Speicher, wenn das vorherige voll ist ...

Gibt es für dieses "Problem" vielleicht eine andere Lösung?

Freienstein

jokester

Treue Seele

Beiträge: 125

Wohnort: Mainz

  • Private Nachricht senden

4

29.07.2011, 13:10


C-/C++-Quelltext

1
2
CKlasse *pZeiger;
pZeiger = new CKlasse2[10]

Hey vorsicht, das funktioniert nicht wirklich, auch wenns sich kompilieren lässt. Weil sizeof(CKlasse2) größer sein kann als sizeof(CKlasse) funktioniert die Zeigerarithmetik nicht mehr und ein pZeiger[1] verweist sonst wo hin, vermutlich mitten in ein Objekt rein statt an den Anfang. Do not treat arrays polymorphically.

Wenn weder Anzahl noch Typ vorher feststehen könntest du einfach einen std::vector<Base*> anlegen und immer per vector.push_back(new Derived); neue Elemente einfügen.
"There is a theory which states that if ever anyone discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened" -- Douglas Adams.

Freienstein

Frischling

  • »Freienstein« ist der Autor dieses Themas

Beiträge: 84

Wohnort: Berlin

  • Private Nachricht senden

5

29.07.2011, 13:26

Könntest du mir bitte ein Beispiel machen? Ich blicke da grade nicht ganz durch ^^

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

6

29.07.2011, 13:33

Zitat

Weil sizeof(CKlasse2) größer sein kann als sizeof(CKlasse)

Aber wenn das nicht so ist klappts... wollte das noch erwähnen, war eben aber sehr in Eile, sorry :whistling:

Ein std::vector würde dein Problem sehr elegant lösen. (oder eine std::list wenn du oft in der Mitte Elemente entfernen musst)
Alternativ kannst du auch ein Array von Zeigern auf die Basisklasse anlegen (auf dem Heap oder auf dem Stack) und jeden dieser Zeiger auf ein Objekt der abgeleiteten Klasse verweisen lassen. Vom Prinzip her also eine std::vector<Basisklasse*> im Eigenbau... Nicht sehr elegant, nicht sehr sauber, keineswegs besser als vector, aber aus Lerngründen vllt. nicht verkehrt...
Signaturen werden überbewertet

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

7

29.07.2011, 13:43

Ein Beispiel: (std::list da ich davon ausgehe das oft Einheiten entfernt und hinzugefügt werden)

C-/C++-Quelltext

1
2
3
4
5
6
std::list<Einheit*> einheiten; // Diese Liste speichert mehrere Zeiger auf Objekte vom Typ "Einheit"
einheiten.push_back(new Soldat(500, "Hans")); // Ein Objekt vom Typ Soldat wird auf dem Heap angelegt, der Zeiger darauf zur Liste hinzugefügt (am Ende)

// Wichtig: Da alle Elemente der Liste Zeiger auf Objekte auf dem Heap sind muss der Speicher irgendwann auch wieder frei gegeben werden:
for (std::list<Einheit*>::iterator i = einheiten.begin(); i != einheiten.end(); ++i)
    delete *i; // Lösche den Speicher auf den der Zeiger an dieser Position verweist


Wenn du zum Speichern in der Liste Smart-Pointer verwendest kannst du dir das Aufräumen ersparen... (Du solltest es aber trotzdem erst mal so probieren)
Signaturen werden überbewertet

Freienstein

Frischling

  • »Freienstein« ist der Autor dieses Themas

Beiträge: 84

Wohnort: Berlin

  • Private Nachricht senden

8

29.07.2011, 13:47

Danke :D Das wird gleich mal ausprobiert.

EDIT: Ok, wird wohl doch erst heute Abend ausprobiert werden. Hab noch was zu erledigen ... :wacko:

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Freienstein« (29.07.2011, 13:52)


Freienstein

Frischling

  • »Freienstein« ist der Autor dieses Themas

Beiträge: 84

Wohnort: Berlin

  • Private Nachricht senden

9

29.07.2011, 16:04

Das mit dem erstellen und löschen der einzelnen Einheiten funktioniert schonmal. Nur hab ich keinen Plan, wie ich das nun neu erstellte Objekt (in meinem Falle ein Schwertkämpfer) nun seine Aktionen, sprich seine Funktionen aufrufen lassen kann.

Danke schonmal für Hilfe :D

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

10

29.07.2011, 18:51

Am Elegantesten und Besten über virtuelle Funktionen der Basisklasse...
Signaturen werden überbewertet

Werbeanzeige