Hallo
Wenn ich mich nicht irre wird die Unterscheidung zwischen
Erzeugung auf Heap und Stack folgendermaßen vorgenommen:
void test()
{
// auf den Stack
MyClass obj;
// auf dem Heap
MyClass *obj = new MyClass();
}
So weit klar …
So weit, so gut: Die Stack-Erstellung bedeutet ja, dass obj an
den scope der Methode test() und somit an deren Stack gebunden
wird.
‚Run time scope‘!
Doch was passiert in diesem Fall
class MyClass2
{ public:
MyClass obj;
}
Nichts. Das ist eine Deklaration und keine
Instantiierung (siehe Moritz).
Das entspricht ja der Notation für die Erzeugung auf dem
Stack. Aber wo landet das Objekt letztendlich? Auf einem Stack
kann ja nicht sein, da es nicht an den scope irgendeiner
Methode gebunden ist …
Obige Deklaration tut nichts ausser zu deklarieren,
wie das Objekt mal aussehen soll, wenn es instantiiert
(als Variable zum Leben erweckt) wird.
Die Deklaration:
class MyClass2 {
public:
MyClass obj;
};
„deklariert“ ein ‚compound-Objekt‘ (enthält eine
weitere nichttriviale Datenstruktur als Member). Jetzt
kann MyClass bei der Instantiierung an sich intern eine
„Heap allocation“ im Konstruktor machen oder nicht.
Das ist ja nicht ersichtlich.
Selbst wenn die umhüllende Klasse MyClass2 in einem
Block { … } ohne „new“ instantiiert wird (also
auf dem Stack), wird die enthaltene Klasse MyClass
ihre Allokationen trotzdem auf dem Heap durchführen.
Wird MyClass2 per „new“ instantiiert, hat man am Ende
faktisch zwei getrennte Speicherbereiche, den einen
für die umgebende Klasse mit allen nichtdynamisch-
alloziierenden Membern beider Klassen und einen
Speicherbereich aus der Alloziierung der enthaltenen
Klasse.
Grüße
CMБ