Dekonstruktor wird Automatisch bei Vector aufgerufen?

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Raidenkk
Beiträge: 64
Registriert: 27.11.2011, 02:32
Echter Name: Kevin
Wohnort: Bergkamen
Kontaktdaten:

Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von Raidenkk »

Hey,
ich erstelle mit dem Folgenden Befehl eine Instanz von meiner Flasche:

vBottles.push_back (CBottles ());

Sobald ich eine Instanz erstelle reagiert logischerweise der Konstruktor von der Flasche.
Was mir aber Spanisch vorkommt warum auch der Dekonstruktor anschlägt obwohl die Flasche nicht gelöscht wurde.
Optisch ist die Flasche wahrnehmbar und mit der Flasche interagieren kann ich auch also denke ich mal das sie auch nicht gelöscht wurde.
Jetzt stellt sich die Frage wie ist sowas möglich und vor allem ist das Normal oder nicht wenn man eine Flasche mit dem Vector Spawnt das der Dekonstuktor Alarm schlägt?

EDIT:
Ich habe mal 3 Flaschen erstellt und es kommt folgendes in meiner Konsole zum Vorschein:
Bild

Gelöscht wurde aber keine Flasche sie stehen alle 3 samt auf dem Tisch.
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von gdsWizard »

Hallo,


Du erzeugst das Objekt auf dem Stack. Außerdem "lebt" das Objekt nur für den Funktionsaufruf push_back(). Die Destruktoraufrufe sind also korrekt.

Wenn ein Objekt in einem Funktionsaufruf erzeugt wird, dann wird es nach dem Funktionsaufruf auch wieder automatisch zerstört. In dem Screenshot kannst Du gut sehen wie das funktioniert. Da du das Objekt in den Vektor einträgst kann ein ungültiges Objekt eingetragen sein. Das hängt von deiner Vektorklasse ab, ob Sie eine Kopie speichert oder die Reference. Wenn Sie eine Kopie macht dann von einer gültigen CBottles. Sollte die Vektorklasse eine Reference speichern dann ist sie nicht gültig !

Wenn deine Vektorklasse Referenzen speichert solltest du das Objekt mit new erzeugen oder aber das Objekt extra als normale Variable erzeugen:

CBottles a;

vBottles.push_back (a);
Benutzeravatar
Raidenkk
Beiträge: 64
Registriert: 27.11.2011, 02:32
Echter Name: Kevin
Wohnort: Bergkamen
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von Raidenkk »

Ahh da bin ich ja beruhigt und hat auch sinn, ich dachte schon mir ist mal wieder ein Fehler durch die Hand geflossen :)

EDIT:
Ich sollte wirklich auf die Schreibweise im Buch achten schon das 2 mal das ich etwas falsch aufgenommen habe :D

NR1. Dekonstruktor = Destruktor
NR2. Objektorisiert = Objektorientiert

Danke vielmals :)
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von IlikeMyLife »

Ist es nicht sinniger, solche Instanzen auf dem Heap zu erzeugen und diese als Pointer beziehungsweise als Referenz zu übergeben?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von Schrompf »

Nein, ist es nicht unbedingt.

Vergleich im Detail:

Code: Alles auswählen

some_vector.push_back( Object());
- temporäres anonymes Objekt wird auf dem Stack konstruiert: Konstruktor plus ein paar Takte für den Platz auf dem Stack.
- Objekt im Array wird mittels Kopierkonstruktor als Kopie des temporären Objekts erzeugt: Kopierkonstruktor
- temporäres anonymes Objekt wird zerstört: Destruktor

im Vergleich zu:

Code: Alles auswählen

some_vector.push_back( new Object());
- new allokiert Platz auf dem Heap für das Objekt: mehrere tausend Takte.
- Konstruktor
- Zeiger wird im Array gespeichert: ein paar Takte

Theoretisch passiert also weniger, wenn man per new allokiert. Da hast Du also Recht. Jedoch ist new (und das delete dazu) viele hundert Mal teurer als ein Kopierkonstruktor oder Destruktor eines *einfachen* Objekts, so dass es sich für die meisten Objekte lohnt, sie direkt zu speichern.

Unter C++0x mit RValue-Referenzen sieht es sogar noch schlechter aus für die new-Lösung: da wird im Beispiel oben (zweite Zeile) der RValue-Konstruktor benutzt, wodurch auch komplexe Objekte mit Strings oder Containern drin nahezu kostenlos kopierbar sind.

Zusammenfassung: man sollte auch hier nur dann Objekte auf dem Heap konstruieren, wenn man es unter anderen Umständen auch tun würde: komplexe Besitzer-Verhältnisse, Lebensdauer-Steuerung. Aus Performance-Sicht macht man mit new eigentlich nahezu immer Miese. Ganz zu schweigen davon, dass man sich mit new auch die manuelle Zerstörung des Objekts aufhalst, was eine gängige Fehlerquelle ist. Und unnötige Arbeit, da C++ mit dem Destruktor eine so elegante und bequeme Lösung für die meisten Resourcen-Probleme hat.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von kimmi »

Aber darauf achten, dass Copy-Konstruktor sowie ein Assignment- und Equal-Operator da sind. Genaueres dazu findest du hier:http://en.wikipedia.org/wiki/Copy_constructor

Gruß Kimmi
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von IlikeMyLife »

C++ bietet hierzu die möglichkeit eines auto-pointers an.

http://www.cplusplus.com/reference/std/memory/auto_ptr/

diese Variante nutze ich teils sehr gerne um die Fehleranfälligkeit von delete zu umgehen.
Ist allerdings nur eine wage beurteilung meiner seits, da ich dieses selbst erst seid kurzem verwende.
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von kaiserludi »

Ein guter Compiler optimiert dir die Kopie auch weg und verwendet stattdessen das Originalobjekt in der Funktion, wenn er merkt, dass du eh nirgends sonst drauf zugreifst. Das spart dir im Release-Mode dann sowahl new als auch Kopie und kann situationsabhängig sogar etwas schneller als eine Referenz auf ein loakles Stackobjejkt sein. Das hat Krishty hier letztens mal näher ausgeführt.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von Schrompf »

kimmi hat geschrieben:Aber darauf achten, dass Copy-Konstruktor sowie ein Assignment- und Equal-Operator da sind. Genaueres dazu findest du hier:http://en.wikipedia.org/wiki/Copy_constructor
Nein, das kann man so allgemein nicht sagen. Der Compiler erzeugt Kopier-Konstruktor und Zuweisungsoperator, wenn sie fehlen. Und das ist eigentlich immer vorzuziehen, außer man muss eigene Logik ausführen. Aber wenn man obigen Leitsatz (kein new, wenn nicht notwendig) beachtet, bekommt man auch Strukturen und Klassen, für die die automatisch generierten Operatoren völlig ausreichen.

Der Zuweisungsoperator ist ein anderes Blatt. Der wird nicht automatisch vom Compiler erzeugt. Man braucht ihn allerdings auch nicht, wenn man ein Objekt in einen Vector packen will. Der wird erst wichtig, wenn man die STD-Algorithmen verwenden will oder die Klasse als Key für manche Container benutzen will.

Übrigens verursacht auch ein auto_ptr ein new und delete. Man erspart sich damit die Arbeit, manuell das Objekt zu zerstören, ist aber in Sachen Performance noch schlechter als mit manuellem new/delete.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von IlikeMyLife »

@ Schrompf:
dann mal vielen dank für die information was den auto_ptr betrifft. derzeit fällt es bei mir noch nicht so ins gewicht bei meinem umfang des projektes. später hätte ich mich allerdings gefragt, wo ich die performance her bekomme
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von Schrompf »

Och, das passt schon! Auch von new/delete kannst Du einige Millionen pro Sekunde machen. Es ist halt nur (bei schlichten Objekten) um Zehnerpotenzen langsamer als ein Objekt auf dem Stack. Daher wollte ich die ursprüngliche Empfehlung für new nicht unkommentiert stehen lassen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von kaiserludi »

Schrompf hat geschrieben: Der Compiler erzeugt [...] Zuweisungsoperator, wenn sie fehlen.
[...]
Der Zuweisungsoperator ist ein anderes Blatt. Der wird nicht automatisch vom Compiler erzeugt.
Ich bezweifle mal, dass das so stimmt ;)
IlikeMyLife hat geschrieben:@ Schrompf:
dann mal vielen dank für die information was den auto_ptr betrifft. derzeit fällt es bei mir noch nicht so ins gewicht bei meinem umfang des projektes. später hätte ich mich allerdings gefragt, wo ich die performance her bekomme
Das hat Null mit der Projektgröße zu tun. Du musst nicht bei großen Projekten vermehrt auf Performance achten im Verlgeich zu kleinen. Du musst bei den kleinen Teilen eines Programmes drauf achten, welche besonders viel von der gesamten Ausführungszeit fressen: In der Regel sind das Codeabschnitte, die sehr sehr häufig ausgeführt werden und meist ziemlich low-level sind.Es bringt um 1.000 mal mehr, etwas zu optimieren, was 1µs dauert und 10 Millionen mal ausgeführt wird, als etwas, was 10ms dauert, aber nur einmal im Programm ausgeführt wird.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von kimmi »

Schrompf hat geschrieben:
kimmi hat geschrieben:Aber darauf achten, dass Copy-Konstruktor sowie ein Assignment- und Equal-Operator da sind. Genaueres dazu findest du hier:http://en.wikipedia.org/wiki/Copy_constructor
Nein, das kann man so allgemein nicht sagen. Der Compiler erzeugt Kopier-Konstruktor und Zuweisungsoperator, wenn sie fehlen. Und das ist eigentlich immer vorzuziehen, außer man muss eigene Logik ausführen. Aber wenn man obigen Leitsatz (kein new, wenn nicht notwendig) beachtet, bekommt man auch Strukturen und Klassen, für die die automatisch generierten Operatoren völlig ausreichen.
...
Das stimmt aber nur dann, wenn man wirklich komplett auf Pointer und new verzichtet hat. Irgendwie bezweifle ich das hier und deswegen warne ich lieber und weise auf entsprechende Doku hin. Weil dann wird das Problem hoffentlich in der Tiefe verstanden, was gerade an einer kitzligen Setlle wie hier sicher nicht schaden kann :).

Und wenn man einen alten Compiler benutzen muß, kann man leider nicht immer auf modernere Features vertrauen. Da spreche ich aus leidvoller Erfahrung, weil der Prozess, hier einen neuen Compiler einzuführen, komplexer ist als den Code neuzuschreiben.

Gruß Kimmi
Zuletzt geändert von kimmi am 19.12.2011, 11:57, insgesamt 1-mal geändert.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von Schrompf »

kaiserludi hat geschrieben:
Schrompf hat geschrieben: Der Compiler erzeugt [...] Zuweisungsoperator, wenn sie fehlen.
[...]
Der Zuweisungsoperator ist ein anderes Blatt. Der wird nicht automatisch vom Compiler erzeugt.
Ich bezweifle mal, dass das so stimmt ;)
Oh, da habe ich mich vertippt. Ich wollte auf den Vergleichsoperator (Equal Operator in Kimmis Beitrag) Bezug nehmen. Danke für den Hinweis!

@Kimmi: stimmt schon. Mir war es halt wichtig, dass ein evtl. Mitlesender nicht überall die Operatoren selbst implementiert, weil er denkt, dass das so sein muss. Compiler-generierter Code ist eigentlich immer dem manuellen vorzuziehen, solange er den Job erledigt.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von kimmi »

Zustimmung, sehe ich auch so. Aber ich habe auch schon ollen Code um Faktoren schneller gemacht, weil ein Autor zuviel kopiert hatte :). Das kann halt auch mal passieren. Leider leben wir in keiner perfekten Welt.

Gruß Kimmi
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von dot »

Was die Performance der Variante mit new angeht, sollte man auch noch bedenken, dass die eigentlichen Objekte dort irgendwo im Speicher rumliegen und jeder Zugriff über einen Pointer erfolgen muss (zusätzliche Indirektion).

Weil auto_ptr erwähnt wurde: Richig verwendet sollte auto_ptr praktisch keinen Overhead im Vergleich zur "manuellen" benutzung von new/delete haben. Generell sollte man eigentlich auf Smartpointer/RAII setzen, wenn man nicht irgendeinen extrem guten Grund hat es nicht zu tun. Denn ohne ist es praktisch unmöglich Code wirklich exceptionsafe zu halten.
Was auto_ptr angeht ist noch wichtig zu wissen, dass man um keinen Preis der Welt auto_ptr in einen std:: Container packen darf, auch wenn es vielleicht auf den ersten Blick wie eine gute Idee aussieht.
Allerdings ist auto_ptr auch deprecated. Heutzutage sollte man auf auto_ptr verzichten und besser unique_ptr benutzen, das ersetzt auto_ptr vollständig und ist in jeder Hinsicht überlegen. unique_ptr kann man auch in std:: Container packen.
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von IlikeMyLife »

Ich habe mich gestern nachmittag viel mit meinem DirectX11-Framework beschäftigt, an dem ich tüftle...
in diesem Zuge habe ich zu dem auto_ptr noch eine Bemerkung zu machen. Es mag zwar Stimmen, dass ein auto_ptr mehr an kosten hat, als new und delete, dazu habe ich noch in erfahrung bringen können, dass sich der auto_ptr scheinbar um fehlerbehandlungen kümmert.

EDIT:
@ dot: habe deinen Kommentar zum unique_ptr erst später gelesen als ich diesen post geschrieben habe :-)

EDIT2:
Grade gefunden:
http://www.humbug.in/stackoverflow/de/s ... 51099.html
Hinweis: lest die englische und nicht die deutsche Version. Ist doch sehr verwirrend die Übersetzung ;-)
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von Artificial Mind »

Okay diese deutsche Übersetzung ist echt der Hammer :D vielen Dank für die beste std::-Übersetzung die ich je gesehen habe.
joggel

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von joggel »

In welcher Welt wird denn "std::" als "Geschlechtskrankheit" übersetzt?
Ich bin verwirrt :D
joggel

Re: Dekonstruktor wird Automatisch bei Vector aufgerufen?

Beitrag von joggel »

Aahhh, okay! Das erklärt es :)
[Edit]
Also, ist trotzdem ein erstes Thema. Nicht das der Eindruck entsteht, ich finde Geschlechtskrankheiten lustig.
Ich fand nur die Übersetzung witzig...
Antworten