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

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

1

02.07.2006, 17:25

[OOP] Mehrere Instanzen einer Klasse, aber bitte geordnet

Ich denke mal mein Problem ist sehr grundlegend, bitte in die richtige Richtung schubsen =)

Momentan arbeite ich an einem Leveleditor, das erstellte Level ist sinnigerweise eine Klasse. Bisher hab ich dieses Level immer in der WinMain Funktion erstellt, das sah dann ca so aus

C-/C++-Quelltext

1
2
3
    // Wir haben Spaß und erschaffen ein Level

    Level myLevel(hInst);
    myLevel.openFile("dialog");
(Die Übergabe der Instanz ist schwachfug, war aber bisher noch nicht dazu gekommen das zu ändern.)

Das man mit dieser Methode nicht wirklich einen Blumentopf gewinnen kann leuchte ein denk ich mal, es gibt eben immer nur ein Level. Nun will ich also mehrere Level paralel "offen" haben können. Die Erstellung eines neuen Levels funktioniert über einen Dialog mit eigener Nachrichtenfunktion. Bisher habe ich auch hier das einzig verfügbare Level sozusagen immer wieder neu geladen. Sieht dann etwa so aus

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
                    // Wir holen die Größe des Levels

                    SendDlgItemMessageW(hDlg, ID::NEWLEVEL_EDITSIZE, WM_GETTEXT, 511, (LPARAM)cBuffer);
                    tempLevel.iSize = _wtoi(cBuffer);

                    tempLevel.sArea = "default";
                    tempLevel.sName = "dialog";         

                    Global::getInst()->getLevel()->openNew(tempLevel);

                    EndDialog(hDlg, 0);
                    return (true);

tempLevel ist dabei eine Struktur, tut aber, denke ich mal, nichts zur Sache.

Soweit also mein vorheriges Vorgehen. Diese Methode geht natürlich in die Binsen wenn ich nicht schon ein Level vorher initialisiere. Nun will ich dem Nutzer aber die Möglichkeit geben zwischen verschiedenen Leveln zu wechseln und möchte dabei nicht immer wieder ein einziges Level neu laden.

Wie das geht? Ich steh wie ein Ochs vorm Berg ... Wenn ich was wichtiges vergessen hab bitte sagen, ich freue mich über jeden konstruktiven Beitrag.

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

2

02.07.2006, 17:39

Eben im Chat aufgekommen: std::list oder std::vector ? Wäre eins der beiden als Ansatz tauglich? Was eher? Und warum?

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

3

02.07.2006, 18:55

Durch dein genaues Vorhaben steig ich zwar grad nicht durch aber zu std::list und std::vector hab ich vor kurzem erst was gelesen.

std::list ist etwas dynamischer, was das Einfügen von neuen Elementen angeht, da jedes Element einzeln Speicher bekommt und dann mit seinem Vorgänger / Nachfolger verknüpft wird. Dafür muss man auch beim Zugriff hinnehmen, dass jedes Element woanders im Speicher liegt und somit nur über die Iteratoren gescheit ansprechbar ist.

std::vector legt wie in einem Array alle Elemente hintereinander an - damit ist es auch möglich, wie ein Array darauf zuzugreifen (schneller). Der Nachteil liegt im Einfügen und entfernen der Elemente, da hier sehr oft der komplette Vector neu zugewiesen werden muss.
Wenn die Elemente im Vector entsprechend klein sind allociert std::vector gleich noch einige Plätze im voraus und kann damit an Performance zunehmen. Bei kompletten Klassen ist es aber im Normalfall so, dass nur wenige Speicherplätze im voraus allociert werden und somit häufiges Einfügen und Entfernen recht viel Performance frisst.

Fazit: Kleine Elemente (auch Pointer auf Klassen!) werden im Vector fast immer schneller gehandhabt. Bei größeren Sachen sollte man überlegen, ob Zugriff oder Veränderungen wichtiger sind.
Listen sind wesentlich dynamischer im Einfügen und entfernen von großen Elementen.

Musst jetzt selbst wissen, was du brauchst.

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

4

02.07.2006, 22:08

In Kladde würde der Ablauf bei mir in etwa so aussehen:
[list]
Namen des Level abfragen
Level schon in der Liste?
wenn ja, dann Level aus der Liste ist das Ergebnis und finí
Neues Level-Objekt anlegen
neues Level-Objekt in die Liste werfen
Level aus Datei in das neue Level-Objekt laden (wenn der nicht komplett neu ist)
neues Level-Objekt is das Ergebnis und finí
[/list]
Noch ein paar weitere Gedanken dazu, die evtl. einen Fingerzeig beinhalten können:

In meiner Liste würde ich generell nur Zeiger auf Level-Objekte verwalten, weil es in der Natur einer Level-Struktur liegt, eher komplex (und damit gross) zu sein.

Ich brauche nur eine Liste, in der Level gespeichert sind, aber beliebig viele Level-Objekte der selben (Basis-)Klasse.

Level Objekte kann man mit "new" an der Stelle erzeugen, wo man sie braucht. So kann man auch das erste Level-Objekt erzeugen.

MfG,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

5

02.07.2006, 22:39

Danke, für eine Person war ich dann ja wohl doch verständlich =) Ich werd mich dann mal tiefer in std::list eingraben.

Btw, ich hab einen peinlichen Gedankenfehler gemacht ... Dachte das Level würde auch "verschwinden" wie eine Variable wenn ich es in einer tiefen Schleife erzeuge, ups ^^

Eine Frage noch dazu:
Wie erstell ich denn mehrere Objekte? Die müssten dann doch alle verschiedene Namen haben? Das Schema

C-/C++-Quelltext

1
2
Level tempLevel(1,2,3)
//Übergabe an die Liste
Kann ich ja nur einmal aufrufen? Sonst hab ich ja das eine Objekt nur wieder neu initialisiert?

OOP Newb hier ^^

Lemming

Alter Hase

Beiträge: 550

Beruf: Schüler

  • Private Nachricht senden

6

03.07.2006, 00:40

Zitat von »"Das Gurke"«

Eine Frage noch dazu:
Wie erstell ich denn mehrere Objekte? Die müssten dann doch alle verschiedene Namen haben? Das Schema

C-/C++-Quelltext

1
2
Level tempLevel(1,2,3)
//Übergabe an die Liste
Kann ich ja nur einmal aufrufen? Sonst hab ich ja das eine Objekt nur wieder neu initialisiert?

diese frage kannst du für dich am besten auf die folgende art und weise klären:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class AnyClass;
std::ostream& operator<< (std::ostream& ost, AnyClass& ac);

class AnyClass
{
    friend std::ostream& operator<< (std::ostream& ost, AnyClass& ac);
public:
    AnyClass(int i = 0) : _i(i){}

    int operator ++(void){return _i++;}

protected:
    int _i;
};

std::ostream& operator<< (std::ostream& ost, AnyClass& ac)
{
    return ost << ac._i;
}

void main(void)
{
    AnyClass a(0);
    for(unsigned int i = 0; i < 5; i++)
    {
        AnyClass b(0);
        ++a;
        ++b;
        std::cout << "a= " << a << "; b= " << b << std::endl;
    }

    std::cin.sync();
    std::cin.get();
}

Ausgabe:

Zitat

a= 1; b= 1
a= 2; b= 1
a= 3; b= 1
a= 4; b= 1
a= 5; b= 1

die komische klasse hab ich nur gemacht um zu verdeutlichen, dass das auch für OOP gilt!


wenn du das temporäre objekt in der schleife dazu nutzen willst neue instanzen in eine liste einzufügen bleibt dir keine andere wahl, als mit pointer und new zu arbeiten. denn in der schleife vorkommende instanzen haben nur dort gültigkeit und werden nache einem durchlauf gekillt. wie du an der ausgabe der kleinen demo unschwer erkennen kannst
Es gibt Probleme, die kann man nicht lösen.
Für alles andere gibt es C++...

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

7

03.07.2006, 02:20

Zitat von »"Das Gurke"«

Das Schema

C-/C++-Quelltext

1
2
Level tempLevel(1,2,3)
//Übergabe an die Liste
Kann ich ja nur einmal aufrufen? Sonst hab ich ja das eine Objekt nur wieder neu initialisiert?

OOP Newb hier ^^


Zum dynamischen Erzeugen musst Du "new" nehmen.

C-/C++-Quelltext

1
2
Level *pTempLevel = new Level(wasAuchImmer);
vLevels.push_back(pTempLevel);
"Games are algorithmic entertainment."

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

8

03.07.2006, 12:33

Nur mal so am Rande... das Problem, das du hier beschreibts hat nichts mit OOP zu tun, weil C++ != OOP.

Sprich: auch in C++ kann man schrecklich objekt-UN-orientiert programmieren. Umgekehrt wird eher ein Schuh daraus: C++ hilft objektorientiert zu programmieren.

MfG
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Werbeanzeige