2011-11-23 13 views
16

Supongamos que someClass es una clase definida en C# con algún método int doSomething(void), y por simplicidad, que proporciona un constructor sin argumentos. Luego, en C#, las instancias tienen que ser creados en el montón GC:Confuso: creación de instancia de la clase C# en C++

someClass c;     // legit, but only a null pointer in C# 
// c->doSomething()   // would not even compile. 
c = new someClass();   // now it points to an instance of someclass. 
int i = c->doSomething();  

Ahora, si someClass se compila en alguna biblioteca .Net, también se puede utilizar en C++/CLI:

someClass^ cpp_gcpointer = gcnew someClass(); 
int i = cpp_gcpointer->doSomething(); 

¡Así de fácil! ¡Hábil! Por supuesto, esto supone que se ha agregado una referencia a la biblioteca .Net al proyecto y se ha realizado una declaración de uso correspondiente.

Tengo entendido que este es el equivalente preciso de C++/CLI del ejemplo anterior de C# (condensado en una sola línea, este no es el punto en el que estoy interesado). ¿Correcto? (Lo siento, soy nuevo en el tema)

En C++, sin embargo, también

someClass cpp_cauto;    // in C++ declaration implies instantiation 
int i = cpp_cauto.doSomething(); 

es una sintaxis válida. Por curiosidad, intenté esto hoy. Un colega, mirando por encima de mi hombro, estaba dispuesto a apostar que ni siquiera compilaría. Él habría perdido la apuesta. (Esta sigue siendo la clase del ensamblado C#). En realidad produce también el mismo resultado i que el código de los ejemplos anteriores.

Nifty, también, pero - uhmm - ¿qué es exactamente, qué se crea aquí? Mi primera suposición descabellada fue que, detrás de mi espalda, .Net crea dinámicamente una instancia en el montón de gc y cpp_auto es un tipo de envoltorio para este objeto, que se comporta sintácticamente como una instancia de la clase someClass. Pero entonces me encontré con esta página

http://msdn.microsoft.com/en-us/library/ms379617%28v=vs.80%29.aspx#vs05cplus_topic2

Esta página parece dime, que (al menos, si algunaClase fuera una clase de C++) cpp_auto se crea realmente en la pila, lo que, a mi entender, sería el mismo comportamiento que obtienes en C++ clásico. Y algo que no puedes hacer en C# (no puedes, ¿verdad?). Lo que me gustaría saber: ¿la instancia del ensamblado C# también se creó en la pila? ¿Puedes producir binarios .Net en C++ con instancias de clase en la pila que no puedes crear en C#? ¿Y posiblemente esto incluso le dará una ganancia de rendimiento :-)?

Saludos cordiales,

Thomas

Respuesta

12

El link you referenced explica esto en detalle:

C++/CLI permite usar la semántica de la pila con los tipos de referencia. Lo que esto significa es que puede introducir un tipo de referencia usando la sintaxis reservada para asignar objetos en la pila. El compilador se encargará de proporcionarle la semántica que esperaría de C++, y bajo las cubiertas cumplir con los requisitos del CLR al asignar realmente el objeto en el montón administrado.

Básicamente, todavía está haciendo un identificador para el tipo de referencia en el montón administrado, pero pide automáticamente Dispose() en IDisposable implementaciones cuando se sale del ámbito para usted.

La instancia de objeto, sin embargo, todavía se asigna de manera efectiva a través de gcnew (colocada en el montón administrado) y recopilada por el recolector de elementos no utilizados. Esto, también, se explica en detalle:

cuando D se sale del ámbito, su método Dispose serán llamados a permitir que sus recursos sean liberados. Nuevamente, dado que el objeto se asigna realmente desde el montón administrado, el recolector de basura se encargará de liberarlo en su propio tiempo.

Básicamente, todo esto es manejado por el compilador para hacer que el código se vea y funcione como las clases asignadas a la pila estándar de C++, pero en realidad es solo un truco de compilación. El código IL resultante sigue haciendo asignaciones de montón administradas.

+0

Ouch. Entonces encontré la respuesta sin reconocerla. Gracias por señalarme esto :-) – Thomas

+0

@Thomas No hay problema. Es una página grande: tienes que saber qué buscar allí para encontrar la discusión sobre el engaño del compilador;) –

+0

Gracias de nuevo, pero bueno, ves, no es porque sea una página grande. El punto es que entiendo la cita solo después de que me indicaste que responde mi pregunta. Pero tal vez esto es solo la ignorancia de los principiantes. Y luego, por supuesto, la ignorancia es dicha :-) – Thomas

Cuestiones relacionadas