<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>https://arolstar52-zhtest.hf.space/index.php?action=history&amp;feed=atom&amp;title=C%2B%2B%2FCLI</id>
	<title>C++/CLI - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://arolstar52-zhtest.hf.space/index.php?action=history&amp;feed=atom&amp;title=C%2B%2B%2FCLI"/>
	<link rel="alternate" type="text/html" href="https://arolstar52-zhtest.hf.space/index.php?title=C%2B%2B/CLI&amp;action=history"/>
	<updated>2026-07-19T22:40:32Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://arolstar52-zhtest.hf.space/index.php?title=C%2B%2B/CLI&amp;diff=71334&amp;oldid=prev</id>
		<title>imported&gt;Timothyliuxf：​补充 C# 类型</title>
		<link rel="alternate" type="text/html" href="https://arolstar52-zhtest.hf.space/index.php?title=C%2B%2B/CLI&amp;diff=71334&amp;oldid=prev"/>
		<updated>2024-03-19T14:31:10Z</updated>

		<summary type="html">&lt;p&gt;补充 C# 类型&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{noteTA&lt;br /&gt;
|G1=IT&lt;br /&gt;
}}&lt;br /&gt;
{{Infobox programming language&lt;br /&gt;
| name = C++/CLI&lt;br /&gt;
| logo =&lt;br /&gt;
| paradigm = [[结构化编程|结构化]], [[指令式编程|指令式]], [[面向对象编程|面向对象]]&lt;br /&gt;
| family = [[C语言|C]]&lt;br /&gt;
| year = {{Start date and age|2005}}&lt;br /&gt;
| designer = [[Microsoft]]&lt;br /&gt;
| developer = Microsoft&lt;br /&gt;
| latest release version = &lt;br /&gt;
| latest release date = &lt;br /&gt;
| typing =&lt;br /&gt;
| implementations =&lt;br /&gt;
| dialects =&lt;br /&gt;
| influenced_by = [[C++]], [[C++托管扩展]], [[C♯|C#]]&lt;br /&gt;
| influenced =&lt;br /&gt;
| platform = [[通用语言架构]]&lt;br /&gt;
| license =&lt;br /&gt;
| file_ext =&lt;br /&gt;
| website = {{URL|https://docs.microsoft.com/en-us/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp}}&lt;br /&gt;
| wikibooks =&lt;br /&gt;
| versions =&lt;br /&gt;
}}&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;C++/CLI&amp;#039;&amp;#039;&amp;#039;（CLI: &amp;#039;&amp;#039;&amp;#039;C&amp;#039;&amp;#039;&amp;#039;ommon &amp;#039;&amp;#039;&amp;#039;L&amp;#039;&amp;#039;&amp;#039;anguage &amp;#039;&amp;#039;&amp;#039;I&amp;#039;&amp;#039;&amp;#039;nfrastructure）在计算机语言中是一门由[[微软]]设计，用来代替[[C++托管扩展]]（Managed C++，下文使用MC++指代）的语言。这门语言在兼容原有的[[C++]]标准的同时，重新简化了托管代码扩展的语法，提供了更好的代码可读性。和[[微软.NET]]的其他语言一样，[[微软]]向[[Ecma International|ECMA]]提交了C++/CLI的标准化请求，并且被ECMA通过成为正式的标准&amp;lt;ref&amp;gt;{{Cite web |url=http://www.ecma-international.org/publications/standards/Ecma-372.htm |title=ECMA 372 |access-date=2006-08-27 |archive-url=https://web.archive.org/web/20080810165757/http://www.ecma-international.org/publications/standards/Ecma-372.htm |archive-date=2008-08-10 |dead-url=yes }}&amp;lt;/ref&amp;gt;。C++/CLI现在可以被[[Visual C++]] 2005和更高版本的编译器支持。C++/CLI的部分特性已经申请了专利。&lt;br /&gt;
&lt;br /&gt;
== 语法改变 ==&lt;br /&gt;
C++/CLI是一门独立的语言（比如新的关键字），而不是像[[C++托管扩展]]一样是C++的超集&amp;lt;ref name=&amp;quot;转换指南&amp;quot;&amp;gt;{{Cite web |url=http://msdn.microsoft.com/zh-cn/library/ms379603(vs.80).aspx |title=转换指南: 将程序从托管扩展 C++ 迁移到 C++/CLI |accessdate=2008-08-29 |archive-date=2009-01-22 |archive-url=https://web.archive.org/web/20090122124407/http://msdn.microsoft.com/zh-cn/library/ms379603(VS.80).aspx |dead-url=no }}&amp;lt;/ref&amp;gt;。（[[C++托管扩展]]有一些不标准的关键字如__gc和__value）。所以，C++/CLI对于这些语法有较大的改变，尤其是去除了一些意义不明确的关键字，增加了一些对.NET的特性的语言级别的支持&amp;lt;ref name=&amp;quot;转换指南&amp;quot;/&amp;gt;。&lt;br /&gt;
=== 关键字 ===&lt;br /&gt;
有歧义的语法，像MC++的不同版本用新的操作符gcnew区分：在C++/CLI，.NET引用类型的创建需要要使用新的关键字gcnew，以和本地类型区分开&amp;lt;ref name=&amp;quot;转换指南&amp;quot;/&amp;gt;。&lt;br /&gt;
C++/CLI增加了新的泛型概念（书写方式与C++的模板相似，但行为有很大的測試区别）。&lt;br /&gt;
&lt;br /&gt;
== 数据类型 ==&lt;br /&gt;
===基本数据类型===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! C++/CLI基本类型!! System命名空间中对应的类!! C#类型 !!  注释/用法&lt;br /&gt;
|-&lt;br /&gt;
| bool|| System::Boolean|| bool ||  bool dirty = false;&lt;br /&gt;
|-&lt;br /&gt;
| char或signed char || System::SByte|| sbyte || char sp = &amp;#039; &amp;#039;;&lt;br /&gt;
|-&lt;br /&gt;
| unsigned char || System::Byte|| byte || unsigned char ch = &amp;#039;\0&amp;#039;;&lt;br /&gt;
|-&lt;br /&gt;
| wchar_t || System::Char|| char || wchar_t wch = ch;&lt;br /&gt;
|-&lt;br /&gt;
| short|| System::Int16|| short || short s = ch;&lt;br /&gt;
|-&lt;br /&gt;
| unsigned short|| System::UInt16|| ushort || unsigned short s = 0xffff;&lt;br /&gt;
|-&lt;br /&gt;
| int或long|| System::Int32|| int || int ival = s;&lt;br /&gt;
|-&lt;br /&gt;
| unsigned int或unsigned long|| System::UInt32|| uint || unsigned int ui = 0xffffffff;&lt;br /&gt;
|-&lt;br /&gt;
| long long || System::Int64|| long || long long etime = ui;&lt;br /&gt;
|-&lt;br /&gt;
| unsigned long long|| System::UInt64|| ulong || unsigned long long mtime = etime;&lt;br /&gt;
|-&lt;br /&gt;
| float || System::Single|| float || float f = 3.14f;&lt;br /&gt;
|-&lt;br /&gt;
| double或long double|| System::Double|| double || double d = 3.14159;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 句柄（Handle）代替了指针 ===&lt;br /&gt;
回到MC++，有两类指针：用__nogc标识的指针是传统意义上的C++指针，而用__gc标识的指针为.NET中的引用。但在C++/CLI里，唯一的指针就是传统意义上的C++指针，而.NET引用类型使用一个“句柄”来获取，使用新的语法“类名^”代替了MC++的“类名*”。新的句法使得托管和非托管代码混合开发更加方便；它指明了对象将会被[[垃圾回收器]]自动销毁还是手动销毁。&lt;br /&gt;
&lt;br /&gt;
范例代码：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
 // C++托管扩展&lt;br /&gt;
 #using &amp;lt;mscorlib.dll&amp;gt;&lt;br /&gt;
 using namespace System::Collections;&lt;br /&gt;
 __gc class referencetype&lt;br /&gt;
 {&lt;br /&gt;
 protected:&lt;br /&gt;
     String* stringVar;&lt;br /&gt;
     int intArr __gc[];&lt;br /&gt;
     ArrayList* doubleList;&lt;br /&gt;
 public:&lt;br /&gt;
     referencetype(String* str，int* pointer，int number) // 哪个是托管的?&lt;br /&gt;
     {&lt;br /&gt;
         doubleList = new ArrayList();&lt;br /&gt;
         System::Console::WriteLine(str-&amp;gt;Trim() + number.ToString());&lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
 // C++/CLI&lt;br /&gt;
 #using &amp;lt;mscorlib.dll&amp;gt;&lt;br /&gt;
 using namespace System::Collections::Generic;&lt;br /&gt;
 ref class referencetype&lt;br /&gt;
 {&lt;br /&gt;
 protected:&lt;br /&gt;
     String^ stringVar;&lt;br /&gt;
     array&amp;lt;int&amp;gt; intArr;&lt;br /&gt;
     List&amp;lt;double&amp;gt;^ doubleList;&lt;br /&gt;
 public:&lt;br /&gt;
     referencetype(String^ str，int* pointer，int number) // 不会再分不清了吧?&lt;br /&gt;
     {&lt;br /&gt;
         doubleList = gcnew List&amp;lt;double&amp;gt;();&lt;br /&gt;
         System::Console::WriteLine(str-&amp;gt;Trim() + number);&lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===托管类型的定义===&lt;br /&gt;
在CLR中，托管类型是分为引用类型（class）和值类型（struct）的，在C++/CLI中的分别定义方式如下：&lt;br /&gt;
&lt;br /&gt;
引用类型：&lt;br /&gt;
&lt;br /&gt;
    public ref class MyClass&lt;br /&gt;
    {&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
值类型：&lt;br /&gt;
&lt;br /&gt;
    public value class MyClass&lt;br /&gt;
    {&lt;br /&gt;
    }; &lt;br /&gt;
===数组===&lt;br /&gt;
数组现在需要用cli名字空间内的array类声明，语法和STL的vector类似&amp;lt;ref name=&amp;quot;转换指南&amp;quot;/&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
C++/CLI中新增了array&amp;lt;T&amp;gt; ^的方式定义数组。&lt;br /&gt;
&lt;br /&gt;
    array&amp;lt;int&amp;gt; ^a = gcnew array&amp;lt;int&amp;gt;(100) { 1, 2, 3 };&lt;br /&gt;
&lt;br /&gt;
或者使用它的完整版：&lt;br /&gt;
&lt;br /&gt;
    cli::array&amp;lt;int&amp;gt; ^a = gcnew cli::array&amp;lt;int&amp;gt; {1, 2, 3}; &lt;br /&gt;
===System::String===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;string&amp;gt;&lt;br /&gt;
    using namespace std;&lt;br /&gt;
    using namespace System;&lt;br /&gt;
    using namespace System::Runtime::InteropServices;&lt;br /&gt;
&lt;br /&gt;
    string cast_to_string(String^ str)&lt;br /&gt;
    {&lt;br /&gt;
        IntPtr ip = Marshal::StringToHGlobalAnsi(str);&lt;br /&gt;
        const char* ch = static_cast&amp;lt;const char*&amp;gt;(ip.ToPointer());&lt;br /&gt;
        string stdStr = ch;&lt;br /&gt;
        Marshal::FreeHGlobal(ip);&lt;br /&gt;
&lt;br /&gt;
        return stdStr;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===不定参数===&lt;br /&gt;
&lt;br /&gt;
对于C#中的不定参数的语法：&lt;br /&gt;
&lt;br /&gt;
    void foo(params string[] args)&lt;br /&gt;
&lt;br /&gt;
在C++/CLI中对应的版本为：&lt;br /&gt;
&lt;br /&gt;
    void foo(... array&amp;lt;String^&amp;gt;^ args) &lt;br /&gt;
=== 跟踪引用（Tracking reference） ===&lt;br /&gt;
C++/CLI里的一个“跟踪引用”也是一个控制代碼，但它是传地址而不是传值。等同于在[[C♯|C#]]中加了“ref”关键字，或[[Visual Basic .NET]]的“ByRef”。C++/CLI使用“^%”语法来定义一个跟踪引用。与传统C++中的“*&amp;amp;”语法相似。&lt;br /&gt;
&lt;br /&gt;
下面的示例了“跟踪引用”的使用。如果把“^%”改成“^”（也就是使用普通的句柄），10个字符串将不会被修改，而只会生成那些字符串的副本，这些都是因为那些引用已经不是传地址而是传值。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
 int main()&lt;br /&gt;
 {&lt;br /&gt;
     array&amp;lt;String^&amp;gt;^ arr = gcnew array&amp;lt;String^&amp;gt;(10);&lt;br /&gt;
     int i = 0;&lt;br /&gt;
 &lt;br /&gt;
     for each(String^% s in arr)&lt;br /&gt;
         s = gcnew String(i++.ToString());&lt;br /&gt;
 &lt;br /&gt;
     return 0;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
上面的代码示例了用户如何用C++/CLI做一些其他.NET语言不能做的事情，比如C#就不允许在foreach循环中这样做。例如&amp;lt;code&amp;gt;foreach(ref string s in arr)&amp;lt;/code&amp;gt;在C#中是非法的。&lt;br /&gt;
&lt;br /&gt;
=== 析构(Finalizer/Destructor) ===&lt;br /&gt;
C++/CLI的另一个变化就是使用“!类名（）”来声明一个托管类型的“析构方法”（在[[垃圾回收器]]回收对象之前的不确定的时间由CLR调用），而原来的“~类名（）”是用来定义“传统的析构函数”（能被用户自己调用）。另外，下面的例子说明了如何在C++/CLI中托管对象如何自动调用“传统析构函数”。&lt;br /&gt;
&lt;br /&gt;
在一个典型的.NET程序中（例如直接使用[[公共中间语言|CLI]]）编程，可以由用户自己调用的“解构方法”是用实现IDisposable接口，通过编写Dispose方法来实现显式释放资源；而不确定的“解构方法”是通过重载Finalize函数来实现的。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
 // C++/CLI&lt;br /&gt;
 ref class MyClass // :IDisposable (编译器自动实现IDisposable接口)&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
     MyClass();  // 建构函数&lt;br /&gt;
     ~MyClass(); // (确定的) 析构函数 (编译器使用IDisposable.Dispose来实现)&lt;br /&gt;
 protected:&lt;br /&gt;
     !MyClass(); // 解构方法 (不确定的) (编译器通过重载virtual void Finalize来实现) &lt;br /&gt;
 public:&lt;br /&gt;
     static void Test()&lt;br /&gt;
     {&lt;br /&gt;
         MyClass _auto; // 这不是个控制代碼，它将调用MyClass的默认建構函数&lt;br /&gt;
         // 使用_auto对象 &lt;br /&gt;
         // 函数返回前自动调用_auto的析构函数(IDisposable.Dispose，由~MyClass()定义)来释放资源 &lt;br /&gt;
         // 以上代码等效于:  &lt;br /&gt;
         MyClass^ user = gcnew MyClass(); &lt;br /&gt;
         try  {  /* 使用_auto对象 */ } &lt;br /&gt;
         finally  {  delete user; /* 由编译器调用_auto.Dispose() */ } &lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
 // C#&lt;br /&gt;
 class MyClass : IDisposable&lt;br /&gt;
 {&lt;br /&gt;
     public MyClass() {} // 构造函数&lt;br /&gt;
     ~MyClass() {} // 析构方法 (不确定的) (编译器通过重载virtual void Finalize来实现)，与C++/CLI的!MyClass()等效&lt;br /&gt;
     public void Dispose() {} // Dispose方法 &lt;br /&gt;
     public static void Test()&lt;br /&gt;
     {&lt;br /&gt;
         using(MyClass auto = new MyClass())  &lt;br /&gt;
         { /* 使用auto对象 */ }&lt;br /&gt;
         // 因为使用了using句法，编译器自动调用auto.Dispose() &lt;br /&gt;
         // 以上代码等效于: &lt;br /&gt;
         MyClass user = new MyClass();&lt;br /&gt;
         try { /* 使用user对象 */ }&lt;br /&gt;
         finally { user.Dispose(); }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 引用和参考 ==&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
== 外部链接 ==&lt;br /&gt;
*[https://web.archive.org/web/20080810165757/http://www.ecma-international.org/publications/standards/Ecma-372.htm ECMA C++/CLI标准]&lt;br /&gt;
{{程序设计语言|C++/CLI}}&lt;br /&gt;
{{DotNET}}&lt;br /&gt;
{{C语言}}&lt;br /&gt;
&lt;br /&gt;
[[Category:程序设计语言]]&lt;br /&gt;
[[Category:.NET编程语言]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Timothyliuxf</name></author>
	</entry>
</feed>