Du bist nicht angemeldet.

Werbeanzeige

n0_0ne

1x Contest-Sieger

  • »n0_0ne« ist der Autor dieses Themas
  • Private Nachricht senden

1

21.03.2009, 23:30

Effektive Listen von Objekten

Hallo,
Ich als Anfänger was C++ und Spieleprogrammierung im Allgemeinen angeht, frage mich gerade, was wohl die beste Möglichkeit ist, Objekte in eine Spiel, welche pro Frame immer wieder aktualisiert werden müssen, zu verwalten.
Bis jetzt verwende ich die Technik, welche auch im Beispielprojekt am Ende des Buches (c++ für spieleprogrammierer) verwendet wurde, nämlich dass eine "Game"-Klasse eine Liste führt, in der alle Objekte gespeichert, und dann aktualisiert und gerendert werden können.
Diese werden aber beispielsweise einfach mit CObject Asteroid; erzeugt, und dann per push_back in die Liste gelegt. Das nennt man soweit ich weiß Call-by-Value, wobei aber auch erst eine Kopie erzeugt werden muss. Da ich die "Mechanik" von C++ noch nicht ganz durchschaut habe, frage ich mich auch gerade, wann dann das Original, von der die Kopie erzeugt wurde, wieder gelöscht wird.
Außerdem wäre es nicht um einiges performanter, wenn man ein solches Object auf dem Heap erzeugt, und dann nur einen Zeiger in der Liste speichert? Und wann setzt man eigentlich noch mal Referenzen ein?
Sind mal wieder ziemliche Anfängerfragen, aber ich hoffe, es überwindet sich trotzdem jemand und beantwortet sie mir :lol:

2

22.03.2009, 00:17

Re: Effektive Listen von Objekten

Zitat von »"n0_0ne"«

Diese werden aber beispielsweise einfach mit CObject Asteroid; erzeugt, und dann per push_back in die Liste gelegt.
Hm, wieso nicht gleich ein temporäres Objekt einfügen? Das wird eher wegoptimierbar sein.

C-/C++-Quelltext

1
MyList.push_back(MyClass(24, 21)); // temporäres Objekt erzeugen und einfügen

Zitat von »"n0_0ne"«

Da ich die "Mechanik" von C++ noch nicht ganz durchschaut habe, frage ich mich auch gerade, wann dann das Original, von der die Kopie erzeugt wurde, wieder gelöscht wird.
Wie alle Variablen mit statischem Speicherbereich (Stack) beim Verlassen des Gültigkeitsbereichs.

Zitat von »"n0_0ne"«

Außerdem wäre es nicht um einiges performanter, wenn man ein solches Object auf dem Heap erzeugt, und dann nur einen Zeiger in der Liste speichert?
Die Liste erzeugt eine Kopie davon auf dem Heap. Aber wie gesagt wird ein moderner Compiler die Kopie wahrscheinlich wegoptimieren können. Falls du jedoch wirklich Probleme mit der Performance hast, liegen die mit grösster Wahrscheinlichkeit woanders. Also mach dir darüber erst Gedanken, nachdem du nachgewiesen hast, dass das Kopieren beim Einfügen dein Flaschenhals ist.

Zitat von »"n0_0ne"«

Und wann setzt man eigentlich noch mal Referenzen ein?
Sehr oft verwendet man Referenzen bei Parameterübergaben. const-qualifiziert, wenn man ein Objekt übergeben will, das nicht kopiert werden soll; normal, wenn man ein Objekt innerhalb einer Funktion verändern möchte. Sonst braucht man Referenzen oft als Aliase/Verweise auf Variablen. Sie sind ähnlich zu Zeigern, jedoch müssen sie bei der Initialisierung auf ein gültiges Objekt zeigen, ihr Ziel kann nicht geändert werden und die Dereferenzierungssyntax entfällt.

n0_0ne

1x Contest-Sieger

  • »n0_0ne« ist der Autor dieses Themas
  • Private Nachricht senden

3

22.03.2009, 00:34

Danke schonmal für die Antworten :)

Das mit dem temporären Objekt geht bei mir nicht ganz so einfach, weil ich mehrere Methoden des Objekts aufrufe, bevor ich es in die Liste schiebe.

Nachdem was du geschrieben hast, würde ich fast sagen, dass Referenzen bei sowas dann am besten sind? Bei Zeigern hat man eben immer viel "Arbeit" und ansonsten eben den Performanceverlust durchs Kopieren (falls das nicht vom Compiler entfernt wird... hätte nicht gedacht, dass Compiler sogar soweit optimieren können ^^). Also liege ich mit den Referenzen in diesem Fall dann richtig?

PS: Ist mehr eine allgemeine Frage, noch hab ich ~1200FPS (mit 800x600) :D

K-Bal

Alter Hase

Beiträge: 703

Wohnort: Aachen

Beruf: Student (Elektrotechnik, Technische Informatik)

  • Private Nachricht senden

4

22.03.2009, 03:14

Du könntest auch Pointer auf das Objekt speichern, das verursacht weniger Overhead.

n0_0ne

1x Contest-Sieger

  • »n0_0ne« ist der Autor dieses Themas
  • Private Nachricht senden

5

22.03.2009, 03:19

Weniger Overhead als mit Referenzen?

K-Bal

Alter Hase

Beiträge: 703

Wohnort: Aachen

Beruf: Student (Elektrotechnik, Technische Informatik)

  • Private Nachricht senden

6

22.03.2009, 03:54

Soweit ich weiß kann man in einen Container keine Referenzen packen bzw. würden trotzdem Kopien angelegt werden. Kann aber auch sein, dass ich falsch liege, ist mir jetzt etwas zu spät zum recherchieren :D

n0_0ne

1x Contest-Sieger

  • »n0_0ne« ist der Autor dieses Themas
  • Private Nachricht senden

7

22.03.2009, 04:01

Hab eben verzweifelt versucht ein std::list<CObject&> zu verwenden, aber irgendwie krieg ichs mit Referenzen nicht hin... oder es ist wie du sagst, und es geht wirklich nicht ^^ naja, dann halt wieder mit Pointer... hab ich zwar teilweise extrem merkwürdiges Zeug da stehen:
SpriteShot = *((*ItShot)->m_pSpriteObject);
viele lustige Sternchen im quelltext :D aber was solls ^^

the[V]oid

Alter Hase

Beiträge: 778

Wohnort: Aachen

  • Private Nachricht senden

8

22.03.2009, 07:27

Ähm....steh ich grade auf dem Schlauch? Ich war immer der Meinung, dass in den STL-Containern ausschließlich Referenzen gespeichert werden können. Zum Beispiel nimmt ja die push_back-Funktion von std::queue einen Parameter von Typ const T& entgegen. Das heißt, was wir auch für T festlegen, es werden immer nur Referenzen aufgenommen. Deshalb macht auch eine std::list<CObject&> gar keinen Sinn.
<< an dieser Stelle ist eine Signatur verstorben >>

drakon

Supermoderator

Beiträge: 6 521

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

9

22.03.2009, 11:22

Zitat von »"the[V«

oid"]Ähm....steh ich grade auf dem Schlauch? Ich war immer der Meinung, dass in den STL-Containern ausschließlich Referenzen gespeichert werden können. Zum Beispiel nimmt ja die push_back-Funktion von std::queue einen Parameter von Typ const T& entgegen. Das heißt, was wir auch für T festlegen, es werden immer nur Referenzen aufgenommen. Deshalb macht auch eine std::list<CObject&> gar keinen Sinn.


Nein, nein. Das ist nur die Übergabe, da du innerhalbt immer eine Kopie des Typen hast, welchen du bei der Deklaration angibst. Wenn du jetzt also eine std::list<CObject> hast, wird eine Kopie von CObject gespeichert. Wenn du ein std::list<CObject*> hast (also einen Zeiger), wird eine Kopie des Zeigers gespeichert. Die Referenz bei dem push_back ist lediglich da, dass die Übergabe syntaktisch einfacher ist. Es ginge auch mit Zeiger, was aber verwirrend sein könnte. Referenzen machen keinen Sinn zu speichern, weil sie nur einen Alternativnamen anbieten und keinen Speicher brauchen müssen.

Wenn man eine Referenz angibt, dann gibt das einen Compile Fehler.

@n0_0ne:
Dagegen können Referenzen helfen, wenn du das zu unleserlich findest.

the[V]oid

Alter Hase

Beiträge: 778

Wohnort: Aachen

  • Private Nachricht senden

10

22.03.2009, 12:53

Aja, klar, ich glaub ich war noch nicht richtig wach ^^
<< an dieser Stelle ist eine Signatur verstorben >>

Werbeanzeige