C ++ / CLI - C++/CLI
Paradigma | Estruturado , imperativo , orientado a objetos |
---|---|
Família | C |
Projetado por | Microsoft |
Desenvolvedor | Microsoft |
Apareceu pela primeira vez | 2005 |
Versão estável | Norma ECMA-372 / Dezembro 2005
|
Plataforma | Infraestrutura de linguagem comum |
Local na rede Internet | www |
Influenciado por | |
C ++ , extensões gerenciadas para C ++ , C # |
C ++ / CLI (C ++ modificado para Common Language Infrastructure ) é uma especificação de linguagem criada pela Microsoft que substitui Managed Extensions para C ++ . É uma revisão completa que simplifica a sintaxe C ++ gerenciada agora obsoleta e fornece interoperabilidade com linguagens Microsoft .NET, como C # . C ++ / CLI foi padronizado pela Ecma como ECMA-372 . Atualmente, está disponível no Visual Studio 2005, 2008, 2010, 2012, 2013, 2015, 2017 e 2019, incluindo as edições Express.
Mudanças de sintaxe
C ++ / CLI deve ser pensado como uma linguagem própria (com um novo conjunto de palavras-chave, por exemplo), em vez do C ++ gerenciado orientado a superconjunto C ++ (MC ++) (cujas palavras-chave não padrão eram estilizadas como __gc
ou __value
). Por causa disso, há algumas mudanças sintáticas importantes, especialmente relacionadas à eliminação de identificadores ambíguos e à adição de recursos específicos do .NET.
Muitas sintaxes conflitantes, como as várias versões do operador em MC ++, foram divididas: em C ++ / CLI, os tipos de referência .NET são criados com a nova palavra-chave (isto é, coleta de lixo new ()). Além disso, C ++ / CLI introduziu o conceito de genéricos do .NET (semelhante, para os fins mais comuns, aos modelos C ++ padrão, mas bastante diferente em sua implementação).
new()
gcnew
Alças
Em MC ++, havia dois tipos diferentes de ponteiros : __nogc
ponteiros eram ponteiros normais de C ++, enquanto __gc
ponteiros funcionavam em tipos de referência .NET. Em C ++ / CLI, entretanto, o único tipo de ponteiro é o ponteiro normal de C ++, enquanto os tipos de referência .NET são acessados por meio de um "identificador", com a nova sintaxe (em vez de ). Essa nova construção é especialmente útil quando gerenciado e o código C ++ padrão é misturado; ele esclarece quais objetos estão sob a coleta de lixo automática .NET e quais objetos o programador deve se lembrar de destruir explicitamente.
ClassName^
ClassName*
Referências de rastreamento
Uma referência de rastreamento em C ++ / CLI é um identificador de uma variável passada por referência. É semelhante em conceito ao uso de " *&
" (referência a um ponteiro) em C ++ padrão e (em declarações de função) corresponde à ref
palavra-chave " " aplicada a tipos em C # ou " ByRef
" em Visual Basic .NET . C ++ / CLI usa uma ^%
sintaxe " " para indicar uma referência de rastreamento a um identificador.
O código a seguir mostra um exemplo do uso de referências de rastreamento. Substituir a referência de rastreamento por uma variável de identificador regular deixaria o array de string resultante com 10 identificadores de string não inicializados, já que apenas cópias dos identificadores de string no array seriam definidas, devido ao fato de serem passados por valor em vez de por referência.
int main()
{
array<String^> ^arr = gcnew array<String^>(10);
int i = 0;
for each(String^% s in arr) {
s = i++.ToString();
}
return 0;
}
Observe que isso seria ilegal em C #, que não permite que os foreach
loops passem valores por referência. Portanto, uma solução alternativa seria necessária.
Finalizadores e variáveis automáticas
Outra mudança em C ++ / CLI é a introdução da sintaxe do finalizador , um tipo especial de destruidor não determinístico que é executado como parte da rotina de coleta de lixo . A sintaxe do destruidor C ++ também existe para objetos gerenciados e reflete melhor a semântica C ++ "tradicional" de destruição determinística (isto é, destruidores que podem ser chamados pelo código do usuário com ).
!ClassName()
~ClassName()
delete
No paradigma .NET bruto, o modelo de destruição não determinística substitui o Finalize
método protegido da Object
classe raiz , enquanto o modelo determinístico é implementado por meio do método de IDisposable
interface Dispose
(no qual o compilador C ++ / CLI transforma o destruidor). Objetos de código C # ou VB.NET que substituem o método Dispose podem ser descartados manualmente em C ++ / CLI delete
da mesma forma que as classes .NET em C ++ / CLI podem.
// C++/CLI
ref class MyClass
{
public:
MyClass(); // constructor
~MyClass(); // (deterministic) destructor (implemented as IDisposable.Dispose())
protected:
!MyClass(); // finalizer (non-deterministic destructor) (implemented as Finalize())
public:
static void Test()
{
MyClass automatic; // Not a handle, no initialization: compiler calls constructor here
MyClass ^user = gcnew MyClass();
delete user;
// Compiler calls automatic's destructor when automatic goes out of scope
}
};
Sobrecarga do operador
A sobrecarga do operador funciona de forma análoga ao C ++ padrão. Todo * se torna um ^, todo & se torna um%, mas o resto da sintaxe permanece inalterado, exceto por uma importante adição: para classes .NET, a sobrecarga de operador é possível não apenas para as próprias classes, mas também para referências a essas classes. Esse recurso é necessário para fornecer a uma classe ref a semântica para a sobrecarga de operador esperada das classes ref .NET. (Em reverso, isso também significa que para classes ref do .NET framework, a sobrecarga do operador de referência geralmente é implementada implicitamente em C ++ / CLI.)
Por exemplo, comparar duas referências de String distintas (String ^) por meio do operador == resultará em true sempre que as duas strings forem iguais. A sobrecarga do operador é estática, no entanto. Portanto, a conversão para Object ^ removerá a semântica de sobrecarga.
//effects of reference operator overloading
String ^s1 = "abc";
String ^s2 = "ab" + "c";
Object ^o1 = s1;
Object ^o2 = s2;
s1 == s2; // true
o1 == o2; // false
Interoperabilidade C ++ / C #
C ++ / CLI permite que programas C ++ consumam programas C # em DLLs C #. Aqui, a palavra-chave #using mostra ao compilador onde a DLL está localizada para seus metadados de compilação. Este exemplo simples não requer organização de dados .
#include "stdafx.h"
using namespace System;
#using "...MyCS.dll"
int main(array<System::String ^> ^args) {
double x = MyCS::Class1::add(40.1, 1.9);
return 0;
}
O conteúdo do código-fonte C # de MyCS.DLL.
namespace MyCS {
public class Class1 {
public static double add(double a, double b) {
return a + b;
}
}
}
Este exemplo mostra como as strings são organizadas de strings C ++ para strings chamáveis de C # e de volta para strings C ++. O marshalling de string copia o conteúdo da string para formulários utilizáveis em diferentes ambientes.
#include <string>
#include <iostream>
#include <msclr\marshal_cppstd.h>
#include "stdafx.h"
using namespace System;
#using "..MyCS.dll"
int main() {
std::string s = "I am cat";
System::String^ clrString = msclr::interop::marshal_as<System::String^>(s); // string usable from C#
System::String^ t = MyCS::Class1::process(clrString); // call C# function
std::string cppString = msclr::interop::marshal_as<std::string>(t); // string usable from C++
std::cout << "Hello, C++/C# Interop!" << std::endl;
std::cout << cppString << std::endl;
return 0;
}
O código C # não reconhece C ++ de forma alguma.
namespace MyCS {
public class Class1 {
public static string process(string a) {
return a.Replace("cat", "dog") + " with a tail";
}
}
}
A interoperabilidade C ++ / C # permite C ++ acesso simplificado a todo o mundo de recursos .NET.
C ++ / CX
C ++ / CX direcionado ao WinRT , embora produza código totalmente não gerenciado, empresta a sintaxe ref e ^ para os componentes de contagem de referência do WinRT, que são semelhantes aos "objetos" COM .
Referências
links externos
- ECMA 372: Especificação de linguagem C ++ / CLI
- Herb Sutter : Palavras-chave C ++ / CLI: nos bastidores
- Herb Sutter : Justificativa C ++ / CLI
- Documentação do MSDN para C ++ / CLI
- Pedido de patente referente a espaços em branco em palavras-chave
- Visualizações de Bjarne Stroustrup (designer / autor de C ++) em C ++ / CLI
- Stanley B. Lippman : Olá, C ++ / CLI
- Stanley B. Lippman : Por que C ++ / CLI é compatível com modelos para tipos CLI e mecanismo genérico CLI