C ++ / CLI (C ++ modificado para Common Language Infrastructure ) es una especificación de lenguaje creada por Microsoft que reemplaza a las extensiones administradas para C ++ . Es una revisión completa que simplifica la ahora obsoleta sintaxis de Managed C ++ [1] y proporciona interoperabilidad con lenguajes Microsoft .NET como C # . C ++ / CLI fue estandarizado por Ecma como ECMA-372 . Actualmente está disponible en Visual Studio 2005, 2008, 2010, 2012, 2013, 2015, 2017 y 2019, incluidas las ediciones Express.
Paradigma | Estructurado , imperativo , orientado a objetos |
---|---|
Familia | C |
Diseñada por | Microsoft |
Desarrollador | Microsoft |
Apareció por primera vez | 2005 |
Lanzamiento estable | Norma ECMA-372 / Diciembre de 2005 |
Plataforma | Infraestructura de lenguaje común |
Sitio web | www |
Influenciado por | |
C ++ , extensiones administradas para C ++ , C # |
Cambios de sintaxis
C ++ / CLI debe considerarse como un lenguaje propio (con un nuevo conjunto de palabras clave, por ejemplo), en lugar del C ++ orientado a superconjuntos de C ++ (MC ++) (cuyas palabras clave no estándar tenían el estilo __gc
o __value
). Debido a esto, hay algunos cambios sintácticos importantes, especialmente relacionados con la eliminación de identificadores ambiguos y la adición de características específicas de .NET.
Muchas sintaxis conflictivas, como las múltiples versiones del operador en MC ++, se han dividido: en C ++ / CLI, los tipos de referencia de .NET se crean con la nueva palabra clave (es decir, basura recolectada new ()). Además, C ++ / CLI ha introducido el concepto de genéricos de .NET (similar, para los propósitos más comunes, a las plantillas estándar de C ++, pero bastante diferente en su implementación).new()
gcnew
Manejas
En MC ++, había dos tipos diferentes de punteros : los __nogc
punteros eran punteros normales de C ++, mientras que los __gc
punteros funcionaban en tipos de referencia .NET. En C ++ / CLI, sin embargo, el único tipo de puntero es el puntero C ++ normal, mientras que se accede a los tipos de referencia .NET a través de un "identificador", con la nueva sintaxis (en lugar de ). Esta nueva construcción es especialmente útil cuando se mezcla código C ++ estándar y administrado; aclara qué objetos están bajo la recolección automática de basura .NET y qué objetos el programador debe recordar destruir explícitamente.ClassName^
ClassName*
Seguimiento de referencias
Una referencia de seguimiento en C ++ / CLI es un identificador de una variable pasada por referencia. Es similar en concepto a usar " *&
" (referencia a un puntero) en C ++ estándar, y (en declaraciones de función) corresponde a la ref
palabra clave " " aplicada a tipos en C #, o " ByRef
" en Visual Basic .NET . C ++ / CLI usa una ^%
sintaxis " " para indicar una referencia de seguimiento a un identificador.
El siguiente código muestra un ejemplo del uso de referencias de seguimiento. Reemplazar la referencia de seguimiento con una variable de identificador regular dejaría la matriz de cadenas resultante con 10 identificadores de cadena no inicializados, ya que solo se establecerían copias de los identificadores de cadena en la matriz, debido a que se pasan por valor en lugar de por referencia.
int main () { matriz < Cadena ^> ^ arr = gcnew matriz < Cadena ^> ( 10 ); int i = 0 ; para cada ( String ^% s in arr ) { s = i ++ . ToString (); } return 0 ; }
Tenga en cuenta que esto sería ilegal en C #, que no permite que los foreach
bucles pasen valores por referencia. Por lo tanto, se necesitaría una solución alternativa.
Finalizadores y variables automáticas
Otro cambio en C ++ / CLI es la introducción de la sintaxis del finalizador , un tipo especial de destructor no determinista que se ejecuta como parte de la rutina de recolección de basura . La sintaxis de destructor de C ++ también existe para objetos administrados y refleja mejor la semántica "tradicional" de C ++ de destrucción determinista (es decir, destructores que pueden ser llamados por código de usuario con ).!ClassName()
~ClassName()
delete
En el paradigma .NET en bruto, el modelo de destrucción no determinista anula el Finalize
método protegido de la Object
clase raíz , mientras que el modelo determinista se implementa a través del método de IDisposable
interfazDispose
(en el que el compilador C ++ / CLI convierte el destructor). Los objetos de código C # o VB.NET que anulan el método Dispose pueden eliminarse manualmente en C ++ / CLI con delete
las clases .NET en C ++ / CLI.
// C ++ / CLI ref class MyClass { public : MyClass (); // constructor ~ MyClass (); // destructor (determinista) (implementado como IDisposable.Dispose ()) protegida : ! MyClass (); // finalizador (destructor no determinista) (implementado como Finalize ())público : test vacío estático () { MyClass automático ; // No es un identificador, no hay inicialización: el compilador llama al constructor aquí MyClass ^ usuario = gcnew MyClass (); eliminar usuario ; // El compilador llama al destructor de automatic cuando automatic sale del alcance } };
Sobrecarga del operador
La sobrecarga del operador funciona de forma análoga a C ++ estándar. Cada * se convierte en ^, cada & se convierte en%, pero el resto de la sintaxis no se modifica, excepto por una adición importante: para las clases .NET, la sobrecarga de operadores es posible no solo para las clases en sí, sino también para las referencias a esas clases. Esta característica es necesaria para dar a una clase de referencia la semántica para la sobrecarga del operador esperada de las clases de referencia de .NET. (A la inversa, esto también significa que para las clases de referencia de .NET framework, la sobrecarga del operador de referencia a menudo se implementa implícitamente en C ++ / CLI).
Por ejemplo, comparar dos referencias de cadena distintas (Cadena ^) mediante el operador == dará verdadero cuando las dos cadenas sean iguales. Sin embargo, la sobrecarga del operador es estática. Por lo tanto, la conversión a Object ^ eliminará la semántica de sobrecarga.
// efectos de la sobrecarga del operador de referencia String ^ s1 = "abc" ; Cadena ^ s2 = "ab" + "c" ; Objeto ^ o1 = s1 ; Objeto ^ o2 = s2 ; s1 == s2 ; // verdadero o1 == o2 ; // falso
Interoperabilidad C ++ / C #
C ++ / CLI permite que los programas C ++ consuman programas C # en DLL de C #. [2] Aquí la palabra clave #using muestra el compilador donde se encuentra la DLL para sus metadatos de compilación. Este simple ejemplo no requiere una clasificación de datos .
#include "stdafx.h"usando el sistema de espacio de nombres ; #utilizando "... MyCS.dll"int main ( matriz < System :: String ^> ^ args ) { double x = MyCS :: Class1 :: add ( 40.1 , 1.9 ); return 0 ; }
El contenido del código fuente C # de MyCS.DLL.
namespace MyCS { public class Class1 { public static double add ( doble a , doble b ) { return a + b ; } } }
Este ejemplo muestra cómo se calculan las cadenas de cadenas de C ++ a cadenas invocables desde C # y luego de nuevo a cadenas de C ++. La clasificación de cadenas copia el contenido de la cadena en formularios utilizables en los diferentes entornos.
#include #include #include #include "stdafx.h"usando el sistema de espacio de nombres ; #utilizando "..MyCS.dll"int main () { std :: string s = "Soy un gato" ; Sistema :: Cadena ^ clrString = msclr :: interoperabilidad :: marshal_as < System :: Cadena ^> ( s ); // cadena utilizable desde C # System :: String ^ t = MyCS :: Class1 :: process ( clrString ); // llamada C # función std :: string cppString = msclr :: interoperabilidad :: marshal_as < std :: string > ( t ); // cadena utilizable desde C ++ std :: cout << "¡Hola, C ++ / C # Interop!" << std :: endl ; std :: cout << cppString << std :: endl ; return 0 ; }
El código C # no es de ninguna manera compatible con C ++.
espacio de nombres MyCS { clase pública Class1 { proceso de cadena estática pública ( cadena a ) { devolver a . Reemplaza ( "gato" , "perro" ) + "con una cola" ; } } }
La interoperabilidad C ++ / C # permite un acceso simplificado de C ++ a todo el mundo de las funciones de .NET.
C ++ / CX
C ++ / CX dirigido a WinRT , aunque produce código completamente no administrado, toma prestada la sintaxis ref y ^ para los componentes contados de referencia de WinRT, que son similares a los "objetos" COM . [3]
Referencias
enlaces externos
- ECMA 372: Especificación del lenguaje C ++ / CLI
- Herb Sutter : Palabras clave de C ++ / CLI: Bajo el capó
- Herb Sutter : C ++ / CLI Justificación
- Documentación de MSDN para C ++ / CLI
- Solicitud de patente sobre espacios en blanco en palabras clave
- Vistas de Bjarne Stroustrup (diseñador / autor de C ++) en C ++ / CLI
- Stanley B. Lippman : Hola, C ++ / CLI
- Stanley B. Lippman : Por qué C ++ / CLI admite tanto plantillas para tipos de CLI como el mecanismo genérico de CLI