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

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

21

19.12.2013, 07:04

aber new verwendet man sowieso selten und wenn, dann niemals mehr direkt... :P
Damit bist Du schon der zweite, der das sagt. Ich frage mich wie genau es dann läuft. Beispiele? Gerade bei Polymorphie fällt mir da kein so richtiger Weg rundrum ein.

Polymorphie ist erstmal völlig unabhängig davon, wie die Objekte erzeugt werden. Ich habe in meinen Programmen regelmäßig Objekte am Stack, die dann polymorph verwendet werden. Ich würde sogar fast soweit gehen, das eher als Regelfall, denn als Ausnahme zu bezeichnen...

Wahrscheinlich meint er std::make_shared!

In der Tat, wobei ich eher an make_unique und ähnliches denke, shared_ptr ist vergleichsweise selten wirklich angebracht...

Auf den Stack legen dürfte in vielen Fällen nur bedingt funktionieren. Jedenfalls in den üblichen Fällen, wo ich Objekte dynamisch anhand von Level-Files/Daten erzeuge.

In solchen Fällen hat man es meiner Erfahrung nach allerdings meist direkt mit Collections von Objekten zu tun, wo ich dann einen entsprechenden Container verwenden würde. Dass wirklich mal einzelne Objekte dynamisch erzeugt werden müssen, kommt bei mir eher selten vor...

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

22

19.12.2013, 11:23

Ich würde passend dazu mal const einwerfen. Ich frage mich bei diesem Schlüsselwort einfach, wann und wie oder wieso man es benutzt.

Also der erste Fall ist standardmässig für eine Konstante, das ist ja logisch: const int size = 10;

Aber ich sehe das auch oft bei Funktionsaufrufen: int Fkt(const int foo, const int bar)

Was dieses const macht ist mir vollkommen klar, nur ist es dort so nötig?


EDIT: Ich hoffe es stört niemanden, dass ich jetzt ein anderes Wort in den Raum werfe, aber genau dafür ist dieses Thema ja, dass man über bestimmte Dinge die State of the Art sind/waren/sein könnten, diskutieren kann, dass so vielleicht ein ganz interessanter Standard entsteht.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

23

19.12.2013, 11:37

Im diesem Fall ist es nicht nötig, da es sowieso Kopien sind, die übergeben werden. Man kann es aber auch machen, wenn man nicht möchte, dass die Funktion fälschlicherweise die Variable verändert.
Ansonsten macht man das bei Funktionen oft, wenn man eine Referenz übergibt, welche nicht verändert werden darf (und nur als const Referenz übergeben wird zu Optimierungszwecken, damit keine Kopie gemacht werden muss).

Man sieht das eher bei Strings, auf welche lesend zugegriffen werden muss in der Funktion.

Bei const gilt: Lieber einmal zu viel, als zu wenig. Wegnehmen kann man es nachher immer noch, wenn es keine gute Idee war etwas const zu machen.

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

24

19.12.2013, 12:37

Stimmt, habe das falsch gemacht. Ich meinte natürlich die Übergabe einer Referenz oder eines Pointer. (int Fkt(int &foo, const int &bar);

Aber selbst wenn etwas nur gelesen werden soll, dann kann man es doch normal übergeben und verändert es halt nicht :)

25

19.12.2013, 12:54

const ist eigentlich nie und an keiner Stelle nötig. Möglicherweise kann der Compiler dank const ein paar Sachen mehr Optimieren, aber darum geht es überhaupt nicht.
const ist einfach dafür da, dem Programmierer zu helfen, sein Programm übersichtlicher und robuster zu gestalten. Im Grunde ist es das selbe wie mit öffentlichen (public) Klassenattributen: Man muss sie nicht benutzen, es hilft aber.
Ein Beispiel: Die std::string Klasse bietet die Funktion c_str() an, die dir einen konstanten C-String liefert. Den kannst du zum lesen benutzen, du darfst ihn aber nicht verändern. Man könnte jetzt auf die Idee kommen, einen std::string über seinen C-String zu manipulieren. Aber möglicherweise ist das, was c_str() dir liefert nur eine Darstellung des Strings. Möglicherweise teilen sich 2 gleiche Strings den selben Speicher und erst wenn du den einen veränderst, bekommt er seinen eigenen Speicher. Über die Zugriffsmethode von std::string kann man das problemlos realisieren, aber die Klasse kann einfach nicht mitbekommen, wenn das, was sie als C-String liefert, verändert wird.

Im Grunde genommen, sagt ein const einfach nur "Wenn du das hier änderst, hat es nicht den Effekt, den du erwartest, also verbiete ich es dir, damit du dir einen vernünftigen Weg suchst, das zu tun, was du wirklich tun willst".

Ein zweiter Effekt ist, dass man die Programmkomplexität verringert, indem man durch const sicherstellt, dass etwas nicht verändert werden kann. Es ist ein bisschen wie mit globalen Variablen: Wenn man etwas von jeder Stelle im Code aus verändern kann, wird das Programm unübersichtlich und schwerer zu debuggen. Mit const hingegen kannst du lesenden Zugriff gewähren (der meiste wesentlich weniger problematisch ist), ohne jedesmal eine Kopie anlegen zu müssen (damit das Original auch ja nicht verändert wird). Deshalb empfiehlt es sich, const überall dort zu benutzen, wo es möglich ist.
Lieber dumm fragen, als dumm bleiben!

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

26

19.12.2013, 13:16

In solchen Fällen hat man es meiner Erfahrung nach allerdings meist direkt mit Collections von Objekten zu tun, wo ich dann einen entsprechenden Container verwenden würde.
Und das wäre dann was für einer, wenn Du die Objekte nicht im Heap erstellen und polymorph einen Obertyp verwenden willst?
Typisches Beispiel: XML. Das XML wird geladen und für jeden der verschiedenen Objekt-Typen darin baut man eine Methode, die das XML für diesen Typ parsen und dann eine Instanz des Typs zurückgeben kann. Diese sollen dann polymorph in einer Collection verwendet werden. Wie würdest Du das dann umsetzen?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

27

19.12.2013, 13:32

Ich kann auch einen Container für jeden konkreten Typ haben und die Objekte da drin dann trotzdem polymorph verwenden, wenn nötig. Um Objekte in Container zu packen, brauch ich keine Polymorphie. Die Besitzer von Objekten kennen meiner Erfahrung nach meistens deren konkreten Typ... ;)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

28

19.12.2013, 14:17

Das war überhaupt nicht die Frage. Lies sie bitte noch einmal. Alle erzeugten Objekte sollen in denselben Container, der nur ihren Interface-Typ, aber nicht die konkrete Implementierung kennt. Jede konkrete Implementierung wird in einer Methode geparsed und ein Objekt davon erzeugt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

29

19.12.2013, 14:22

Alle erzeugten Objekte sollen in denselben Container, der nur ihren Interface-Typ, aber nicht die konkrete Implementierung kennt.

Das ist eine Mögliche Lösung, aber eben nicht die einzige. Ich sehe keinen zwingenden Grund, wieso hier alle Objekte unbedingt in den selben Container müssen!?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

30

19.12.2013, 14:52

Was ist, wenn man zur Compile-Zeit noch gar nicht weiß, welche Typen es gibt? Dann fällt die "Ein Container pro Typ"-Lösung ja schonmal raus.
Das kommt z.B. vor, wenn man Objekt-Factories über DLLs nachlädt.

Werbeanzeige