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

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

11

03.07.2013, 20:03

Du solltest auch noch deine Funktion

C-/C++-Quelltext

1
void CFramework::Draw(sf::Sprite Sprite)


ändern in

C-/C++-Quelltext

1
void CFramework::Draw(const sf::Sprite& Sprite)


Beachte das const und das &.
Referenzen scheinst du wohl noch nicht zu kennen. Damit verhinderst du, dass beim Aufrufen der Funktion eine Kopie des Sprite-Objekts erzeugt wird.

Encounter

Frischling

  • »Encounter« ist der Autor dieses Themas

Beiträge: 22

Wohnort: Aachen

  • Private Nachricht senden

12

03.07.2013, 20:22

Hallo David,

danke für deinen Hinweis. Referenzen kenne ich, allerdings muss ich gestehen, dass mir ihr Nutzen nie so 100 % klar geworden ist.
Wenn ich keine Kopie haben möchte, nutze ich Zeiger/Pointer.

Ich verstehe noch nicht ganz, welchen Vorteil mir die Veränderungen bringen.
- Ist die Konstante nicht eigentlich überflüssig, da der Wert ohnehin jedesmal neu übergeben wird und die Variable danach sofort wieder gelöscht (da die Funktion beendet) wird?
- Ok die Referenz kann ich benutzen um nicht einmal den eigentlichen Sprite zu haben und eine Sprite Kopie in der Funktion. Aber macht das in diesem Fall denn einen Unterschied?

Bin gerne bereit das zu verstehen, lerne gerne dazu :D .
Ich war hier und hab ALLES gesehen!

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

13

03.07.2013, 20:52

Ohne Referenz wird von dem Objekt zuerst eine Kopie angefertigt.
Die wird dann in der Funktion benutzt und am Ende wieder zerstört.
Je nach Objekt ist das sehr teuer. Stell dir z.B. vor du übergibst eine Liste mit einer Million Einträgen - dann müsste diese komplett kopiert werden, nur um am Ende wieder zerstört zu werden.

Mit Referenz arbeitet die Funktion auf demselben Objekt, das du ihr übergibst - es wird keine Kopie angefertigt - so wie bei einem Zeiger.
Das const bedeutet, dass das Objekt, auf das die Referenz zeigt, von der Funktion nicht "verändert" wird.
D.h. unter anderem, dass nur const-Methoden aufgerufen werden und keine Member-Variablen verändert werden.

Encounter

Frischling

  • »Encounter« ist der Autor dieses Themas

Beiträge: 22

Wohnort: Aachen

  • Private Nachricht senden

14

03.07.2013, 21:13

Ohne Referenz wird von dem Objekt zuerst eine Kopie angefertigt.
Die wird dann in der Funktion benutzt und am Ende wieder zerstört.
Je nach Objekt ist das sehr teuer. Stell dir z.B. vor du übergibst eine Liste mit einer Million Einträgen - dann müsste diese komplett kopiert werden, nur um am Ende wieder zerstört zu werden.

Mit Referenz arbeitet die Funktion auf demselben Objekt, das du ihr
übergibst - es wird keine Kopie angefertigt - so wie bei einem Zeiger.
Hmm, aber ich dachte immer, ein Zeiger erzeugt auch KEINE Kopie, bis halt auf die Adressvariable?!
Macht es dann nicht auch Sinn mein Window also sf::RenderWindow nicht per Zeiger sonderen Referenz zu übergeben?
Ok, dass das dann Ressourcensparender ist, ist klar. Und du hast natürlich Recht, das man auf soetwas auch bei kleineren Projekten achten sollte.
Das const bedeutet, dass das Objekt, auf das die Referenz zeigt, von der Funktion nicht "verändert" wird.
D.h. unter anderem, dass nur const-Methoden aufgerufen werden und keine Member-Variablen verändert werden.
Ok, also in diesem Fall nicht zwangsweise nötig, aber klarer und sicherer.
Ich war hier und hab ALLES gesehen!

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

15

03.07.2013, 21:28

Zeiger und Referenzen kannst du oft "gleich" verwenden. Da gibt es schon ein paar Unterschiede, aber was du mit Referenzen machen kannst kannst du im Prinzip auch mit Zeigern machen. Jetzt muss ich ein wenig aufpassen was ich sage:) Sicherlich ist es sinnvoll dir noch mal die Kapitel dazu anzuschauen. Für die Übergabe bei Parametern kann man im Prinzip sagen, darf auch null übergeben werden, so nutze Zeiger, ist dies nicht der Fall, so nutze Referenzen.

@BC: Natürlich war das Problem das Laden der Bilder, ich habe die Antwort ja nur erweitert. Sprites neu erzeugen kann man sich ja auch sparen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

16

03.07.2013, 23:33

Es sei erwähnt, dass const sf::Sprite& sowohl rvalues wie auch lvalues akzeptiert. Lässt du allerdings das const weg, ist dies nicht mehr der Fall.
Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
void foo(sf::Sprite& s) { }

foo(sf::Sprite(...)); // klappt nicht, da rvalue

sf::Sprite s;
foo(s); // funktioniert


Und der Unterschied:

C-/C++-Quelltext

1
2
3
4
5
6
void foo(const sf::Sprite& s) { }

foo(sf::Sprite(...)); // klappt, trotz rvalue [1]

sf::Sprite s;
foo(s); // funktioniert ebenso


[1] Der Compiler legt (mal etwaige Optimierungen außen vor gelassen) hierbei die Variable temporär an und übergibt diese an die Funktion.
Aber das nur am Rande, damit du weißt, wieso das const dasteht und was es dir bringt.

Was zu Referenzen und Zeigern:
Zeiger können NULL sein, Referenzen eig. nicht. Du kannst zwar z.B. auf einen Nullpointer referenzieren, aber es ist bei Referenzen umständlicher und somit wesentlich seltener, dass sie NULL sind, als es bei Zeigern passieren kann. Zudem kann eine Referenz nur einmal zugewiesen werden, womit eine versehentlicher NULL Zuweisung in einer Funktion (im Gegensatz zu einem Zeiger) nicht passieren kann.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Encounter

Frischling

  • »Encounter« ist der Autor dieses Themas

Beiträge: 22

Wohnort: Aachen

  • Private Nachricht senden

17

04.07.2013, 12:10

Hey,

danke für den Tipp.
das Problem ist mir bisher gar nicht aufgefallen, weil ich es meistens mit lvalues mache.
Aber ich sollte aus Speichergründen wohl auch mal mehr mit rvalues machen :D

Und das mit den Referenzen habe ich durch euch jetzt schon etwas besser verstanden.
Ich war hier und hab ALLES gesehen!

Werbeanzeige