ref und value class
-
Hallo,
ich lerne gerade C++/CLI und habe einige kurze Fragen:
- value struct/class Typen sind doch prinzipiell für den Stack gedacht, oder?
Z.B:
value class Foo { }; Foo f; // Ein Value type sollte so erzeugt werden (f ist auf dem stack) Foo^ f2 = gcnew Foo; // das geht aber auch
Generell sollte ich ich einen value Type mittels Type name anlegen, oder? Die 2. Zeile geht nur, weil automatisch boxing gemacht wird, oder?
- Ein ref Type ist für den Managed Heap gedacht, oder?
ref class RefClass { }; RefClass^ g = gcnew RefClass; // A RefClass g2; // B
Ref Typen sollte ich wie in Zeile A mit gcnew erzeugen, oder?
Wieso geht Zeile B? Wurde da jetzt in Zeile B ein Objekt erzeugt?
- value struct/class Typen sind doch prinzipiell für den Stack gedacht, oder?
-
Lerner2 schrieb:
Generell sollte ich ich einen value Type mittels Type name anlegen, oder? Die 2. Zeile geht nur, weil automatisch boxing gemacht wird, oder?
Grob ja - ja, Das ^ bedeutet, dass es auf den Managed Heap landet.
Also wird es autoboxt.Lerner2 schrieb:
Ref Typen sollte ich wie in Zeile A mit gcnew erzeugen, oder?
Wieso geht Zeile B? Wurde da jetzt in Zeile B ein Objekt erzeugt?Abgesehen den den "Sonderfall" musst du ref Typen mit gcnew erzeugen.
Der "Sonderfall" bedeutet nur, dass, diese Instanz nichtlangliebig ist und am ende von dessen Gültigkeitsbereich der Destruktor und vorher ggf. Dispose aufgerufen wird. Wenn du aus C# kommst ist das in etwa ein funktionsfüllendesusing
.
-
Rhombicosidodecahedron schrieb:
Lerner2 schrieb:
Generell sollte ich ich einen value Type mittels Type name anlegen, oder? Die 2. Zeile geht nur, weil automatisch boxing gemacht wird, oder?
Grob ja - ja, Das ^ bedeutet, dass es auf den Managed Heap landet.
Also wird es autoboxt.
Hm, also ich habe gerade gelesen, dass Boxing bedeutet einen Value Type in einen Ref Type umzuwandeln.
Also ist zb das hier Boxing:value class Foo { }; Foo f; Foo^ g = f;
Nur Frage ich mich, ob das hier:
Foo^ g2 = gcnew Foo;
überhaupt Boxing ist. Foo ist zwar ein value Type, aber das Ding liegt ja auf dem Managed Heap. Wurde also in der Zeile mit g2 auch ge-autoboxt?
Lerner2 schrieb:
Ref Typen sollte ich wie in Zeile A mit gcnew erzeugen, oder?
Wieso geht Zeile B? Wurde da jetzt in Zeile B ein Objekt erzeugt?Abgesehen den den "Sonderfall" musst du ref Typen mit gcnew erzeugen.
Der "Sonderfall" bedeutet nur, dass, diese Instanz nichtlangliebig ist und am ende von dessen Gültigkeitsbereich der Destruktor und vorher ggf. Dispose aufgerufen wird. Wenn du aus C# kommst ist das in etwa ein funktionsfüllendesusing
.ok, aber wie sieht das technisch aus:
ref class RefClass { }; RefClass k;
Liegt hier das Objekt auf dem Stack oder liegt es im Managed Heap + Boxing?
-
(Kann meinen Beitrag nicht editieren, drum hier der Aktuelle. Kann jemand bitte mein vorletztes Posting löschen? Sorry!)
Rhombicosidodecahedron schrieb:
Grob ja - ja, Das ^ bedeutet, dass es auf den Managed Heap landet.
Also wird es autoboxt.Hm, also ich habe gerade gelesen, dass Boxing bedeutet einen Value Type in einen Ref Type umzuwandeln.
Also ist zb das hier Boxing:value class Foo { }; Foo f; Foo^ g = f;
Nur Frage ich mich, ob das hier:
Foo^ g2 = gcnew Foo;
überhaupt Boxing ist? Foo ist zwar ein value Type, aber das Ding liegt ja auf dem Managed Heap. Wurde also in der Zeile mit g2 auch ge-autoboxt?
Rhombicosidodecahedron schrieb:
Abgesehen den den "Sonderfall" musst du ref Typen mit gcnew erzeugen.
Der "Sonderfall" bedeutet nur, dass, diese Instanz nichtlangliebig ist und am ende von dessen Gültigkeitsbereich der Destruktor und vorher ggf. Dispose aufgerufen wird. Wenn du aus C# kommst ist das in etwa ein funktionsfüllendesusing
.ok, aber wie sieht das technisch aus:
ref class RefClass { }; RefClass k;
Liegt hier das Objekt auf dem Stack oder liegt es im Managed Heap + Boxing?
-
Lerner2 schrieb:
Liegt hier das Objekt auf dem Stack oder liegt es im Managed Heap + Boxing?
Objekte ref-Typen immer im Heap. Boxing ist nur bei value Typen von nöten, wenn sie vom Stack in den ^ "gelangen" sollen und umgekehrt.
-
Rhombicosidodecahedron schrieb:
und am ende von dessen Gültigkeitsbereich der Destruktor und vorher ggf. Dispose aufgerufen wird.
Der Wurm ist das Spice, das Spice ist der Wurm.
Der Destruktor ist das Dispose, das Dispose ist der Destruktor.Abgesehen davon dass ich es garnicht unbedingt Destruktor nennen würde - ist schliesslich nur Dispose mit automatischem Chaining.
-
Rhombicosidodecahedron schrieb:
Lerner2 schrieb:
Liegt hier das Objekt auf dem Stack oder liegt es im Managed Heap + Boxing?
Objekte ref-Typen immer im Heap. Boxing ist nur bei value Typen von nöten, wenn sie vom Stack in den ^ "gelangen" sollen und umgekehrt.
Drum versteh ich ja nicht ganz, wieso das hier:
ref class RefClass { }; RefClass k;
geht. Du sagst ref klassen liegen IMMER im Managed Heap. Ok, das Objekt liegt also auf dem Heap und k verweist darauf. Aber dann ist es ja EXAKT das selbe wie das:
RefClass^ k = gcnew RefClass
Wieso lässt der Compiler überhaupt ein "RefClass k;" zu? Das sieht so aus, als würde das Objekt aufm Stack liegen, was es aber offenbar nicht tut.
-
Lerner2 schrieb:
Wieso lässt der Compiler überhaupt ein "RefClass k;" zu? Das sieht so aus, als würde das Objekt aufm Stack liegen, was es aber offenbar nicht tut.
Dann jetzt deutlich: Syntactic sugar. Oder weil es eine andere Darstellung ist für:
void x(void) { try { RefClass^ k = gcnew RefClass(); /* ... */ } finally { if(k /*!= nullptr*/) delete k; } }
P.S.: Kannst nochmal bei Wikipedia (deutsch, englisch) nachlesen.
hustbaer schrieb:
ist schliesslich nur Dispose mit automatischem Chaining.
WTF
wusste ich nicht, dachte es gäbe den Desktruktor, den Finalizer und dann noch einen Dispose, wenn man IDisposable implementiert, scheinst haben recht zu haben. Danke für den Hinweis.
-
Bezüglich Dispose hier noch eine alte Diskussion:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-242975-and-postdays-is-0-and-postorder-is-asc-and-start-is-10.html