Wann werden Objekte erzeugt?
-
Bashar schrieb:
Da da da
Aha, aha, aha...

Ich sehe meine Vermutung also bestätigt, zumal er auch immer mal wieder mit Begriffen (wie zB statisch) recht schwammig umgeht. Dann vertrau ich bei Unklarheiten mal besser auf mein eigenes Wissen. Ich werd ihn mal nächsten Montag auf ein paar Sachen ansprechen und schauen, was er dazu sagt.
Also Vielen Dank erstmal!
-
p_eter schrieb:
Erzeugung von Objekten: [i]statisch[/i] beim Übersetzen eines Programms [i]dynamisch[/i] beim Interpretieren eines Programmsich weiss gar nicht was ihr habt...
... int a; // statisch ... void f() { static int b; // statisch int c; // dynamisch int d* = new int; // dynamisch }
-
Subjekt schrieb:
p_eter schrieb:
Erzeugung von Objekten: [i]statisch[/i] beim Übersetzen eines Programms [i]dynamisch[/i] beim Interpretieren eines Programmsich weiss gar nicht was ihr habt...
... int a; // statisch ... void f() { static int b; // statisch int c; // dynamisch int d* = new int; // dynamisch }
Sorry, aber falsch:
1. sowohl für die globale Variable als auch die lokale static Variable werden trotz allem erst zur Laufzeit Instanzen angelegt. Dabei wird die globale Variable am Programmanfang, die statische ggf. erst beim ersten Funktionsaufruf instanziert (Objekterzeugung). Hiermit wiederspreche ich dem Script, nicht dir*
2. int c; ist nichts desto trotz eine statische Objekterzeugung (Stack), auch wenn es nichts mit dem static-Schlüsselwort gemein hat.
3. int *d =...; Hier kann man sogar gemein sein und sagen das es zwei Sachen gibt:
a) Der Zeiger wird statisch (auf dem Stack) instanziiert
b) Der intwert selber wird dynamisch (auf dem Heap) instanziiert.Man kann mich gerne korrigieren ;p
* Ich beziehe mich hierbei auf den Wortlaut der Folie die sagt statische Objektinitialisierung auf den Stack, dynamische auf dem Heap. Wobei ich mir nicht sicher bin ob es nicht noch einen dritten bereich für die globalen und statics gab (oder ob die jetzt wirklich Stackbasiert sind)
cu André
-
asc schrieb:
1. sowohl für die globale Variable als auch die lokale static Variable werden trotz allem erst zur Laufzeit Instanzen angelegt.
ja, aber es passiert noch bevor 'main' aufgerufen wird. aber es ist im code festgelegt und man kann zur laufzeit nichts mehr dagegen tun --> statisch
asc schrieb:
Dabei wird die globale Variable am Programmanfang, die statische ggf. erst beim ersten Funktionsaufruf instanziert
eigentlich werden beide vor aufruf von 'main' im selben datensegment (initialisierte variablen) erzeugt. und ich glaube, wenn es instanzen von klassen sind, dann werden sogar die konstruktoren vor dem aufruf von 'main' angesprungen.
asc schrieb:
2. int c; ist nichts desto trotz eine statische Objekterzeugung (Stack)...
es gibt ja wohl kaum was dynamischeres als stackvariablen. man darf es nur nicht mit 'dynamischem speicher' <--> heap memory verwechseln.
asc schrieb:
3. int *d =...; Hier kann man sogar gemein sein und sagen das es zwei Sachen gibt:
ja, das stimmt. einmal den pointer und dann noch das heap-element.

-
Subject schrieb:
asc schrieb:
Dabei wird die globale Variable am Programmanfang, die statische ggf. erst beim ersten Funktionsaufruf instanziert
eigentlich werden beide vor aufruf von 'main' im selben datensegment (initialisierte variablen) erzeugt. und ich glaube, wenn es instanzen von klassen sind, dann werden sogar die konstruktoren vor dem aufruf von 'main' angesprungen.
Der Ctor einer statischen Variablen wird definitiv NICHT vor der main() aufgerufen, sondern beim ersten Mal, wenn der Programmfluß an ihrer Definition vorbeikommt (ja, wenn die Funktion, in der sie vorkommt, zur Initialisierung einer globalen Variablen verwendet wird, kann das vor der main() sein). Wenn du die Funktion überhaupt nicht verwendest, wird die Variable auch nie initialisiert (vermutlich belegt sie trotzdem etwas Platz im Datensegment).
-
naja statisch ist rel.
Lebensdauer spezifisch blockabhängig
-
Subject schrieb:
es gibt ja wohl kaum was dynamischeres als stackvariablen. man darf es nur nicht mit 'dynamischem speicher' <--> heap memory verwechseln.
Ich habe mich bewusst (und das auch hervorgehoben) an die "vorgegebene" Bezeichnung gehalten. Zudem wiederspreche ich der definition Stackvariable = dynamisch.
Wobei ein statisches Objekt laut Vorlesung ein Objekt auf dem Stack ist
Ja, sie werden bezogen auf ihren Scope angelegt und gelöscht, sind aber im Programmcode statisch enthalten. Daher bin ich mit den Bezeichnungen eh nicht ganz zufrieden sondern würde statt statisch / dynamisch genauer differenzieren wollen.
Aber um im üblichen Programmierjagon zu bleiben würde ich bei "dynamisch" nur die Variante mit separater Allozierung verwenden (um nicht noch zusätzliche Anfängerschwierigekeitn mit dem Begriff der dynamischen Speicheralloziierung hervor zu bringen).
Definieren wir doch lieber wo (Stack, Heap, Datensegment) und wann sie angelegt werden (Vor der main, vor oder beim ersten Aufruf, Scopebezogen...). Das würde das ganze zumindestens eindeutiger und leichter Verständlich machen.
-
Bashar schrieb:
Und da auf deiner Folie aber behauptet wird, dass C++-Programme interpretiert werden, kann ich mir auch vorstellen, dass dein Dozent von solchen Feinheiten auch keine Ahnung hat.
Du wirst lachen, es gibt Programme, die von sich behaupten, C++-Interpreter zu sein, z.B. CINT. Wie gut sie darin sind, ist ein ganz anderes Thema (ich muss mich mit dem Muell leider rumschlagen)
-
Ich weiß dass es das gibt, aber es ist bei weitem die Ausnahme. Wieso schlägst du dich damit rum?

-
Es gibt ein Framwork namens ROOT, das eng mit CINT verknuepft ist und in der Hochenergiephysik (Teilchenphysik) viel benutzt wird. Und da ich meine Diplomarbeit in Teilchenphysik schreibe muss ich meine Analyseprogramme mit ROOT schreiben und sitze daher jeden morgen mit Grausen vor diesem Mist. Deletes sind in ROOT z.B. weitgehend verboten, weil es mit den Objekten die man anlegt noch einigen unsichtbaren Schindluder betreibt. Ob man eine Routine einfach interpretieren laesst oder sie vorkompiliert und dann ausfuehren laesst sind zwei verschiedene Paar Schuhe bei ROOT/CINT, ob es auf die eine oder die andere Art die richtigen Includes verlangt oder auf keinen Fall eingebunden haben will ist oft Glueckssache. Mal ganz abgesehen von einem teilweise irrwitzigen Klassendesign in einer riesigen Vererbungshierarchie, die dazu fuehrt, dass man auf der Suche nach der Doku einer Funktion erstmal durch 10-20 header blaettern darf... Ich bin also froh wenn ich hier weg bin!
-
pumuckl schrieb:
Deletes sind in ROOT z.B. weitgehend verboten, weil es mit den Objekten die man anlegt noch einigen unsichtbaren Schindluder betreibt. Ob man eine Routine einfach interpretieren laesst oder sie vorkompiliert und dann ausfuehren laesst sind zwei verschiedene Paar Schuhe bei ROOT/CINT, ob es auf die eine oder die andere Art die richtigen Includes verlangt oder auf keinen Fall eingebunden haben will ist oft Glueckssache.
Das ist ja Mist. Es wäre doch sicher ohne weiteres möglich, einen Interpreter zu implementieren, der sich im Rahmen des vom Standard definierten exakt wie ein Compiler verhält. Zum Beispiel seh ich nicht ein, wieso ein delete nicht möglich sein soll. Alles was er tun muss ist, den Destruktor aufzurufen. Er kann ja das (tote) Objekt noch behalten, wenn es sein muss.
-
nur weil es ein oder zwei seltene ausnahmen gibt sollte man nicht in ein skript schreiben, dass Objekte dynamisch beim Interpretieren eines Programms erzeugt werden, als ob das bei C++ immer so wäre und den leuten damit was falsches beibringen.
-
Bashar schrieb:
Das ist ja Mist. Es wäre doch sicher ohne weiteres möglich, einen Interpreter zu implementieren, der sich im Rahmen des vom Standard definierten exakt wie ein Compiler verhält. Zum Beispiel seh ich nicht ein, wieso ein delete nicht möglich sein soll. Alles was er tun muss ist, den Destruktor aufzurufen. Er kann ja das (tote) Objekt noch behalten, wenn es sein muss.
Allgemein sind deletes da schon möglich. Es ist aber z.B. unter ROOT so, dass man sich immer in einem "aktuellen directory" befindet, meist die zuletzt geöffnete Datei, und dass bei Programmende automatisch alle erzeugten Objekte bestimmter Klassen in diese Datei gespeichert werden. Wenn man, wie dort üblich, die Objekte dynamisch anlegt und dann mit delete zerstört gibts großes Gezeter von ROOT/CINT
Ich muss "hinweis"' Aussage voll zustimmen. man sollte für den Anfang einfach vergessen dass es sowas wie C++-Interpreter gibt und sich auf Compiler orientieren und dazu den Leuten das richtige beibringen.
-
Das von Pumuckl gesagte bezieht sich größtenteils auf das Framework ROOT.
CINT, der eigentliche Interpreter, ist auch ohne ROOT benutzbar und funktioniert im Prinzip ziemlich gut - von ein paar ekligen Bugs mal abgesehen. Es gibt zumindest kein generelles Problem in CINT, was delete oder Destruktoren anginge.
Für Einsteiger ist er trotzdem nicht gemacht.