知识大全 超越C++下一代C++ —C++/CLI简介

Posted 指针

篇首语:少年负壮志,奋烈自有时。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 超越C++下一代C++ —C++/CLI简介相关的知识,希望对你有一定的参考价值。

超越C++下一代C++ —C++/CLI简介  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

一 绪论

  当微软推出VS NET 实现了可扩展的托管C++后 C++程序员们反映不一 尽管大部分的程序员对于能够继续使用C++感到很欣慰 但几乎所有的人对于托管C++提供的晦涩语法感到很痛苦 微软明显从反馈中感觉到托管C++不是那么成功

   年 月 日 ECMA(欧洲计算机制造商协会)宣布成立专家组 负责结合ISO标准C++与通用语言 开发一个可扩展语言的标准 这个新的可扩展语言被称为C++/CLI标准 这个标准将被VS NET 的C++编译器支持

  二 老语法存在的问题

   晦涩繁琐的语法和文法 这两个 双重底线 问题加重了阅读的负担

   二流的CLI支持 相对与C#与VB NET MC++使用不方便的工作区来提供CLI支持 例如 它没有一个一一对应的结构来列举 NET的集合

   C++与 NET粗陋地结合 对于CLI类型 你不能使用C++的特色 例如模板 同样 对于C++类型 你不能使用CLI的特色 例如碎片帐集

   令人混淆的指针 非托管的C++的指针及托管的引用指针都使用*语法 这非常令人混淆 因为 gc指针与托管指针在本质和行为上完全不同

   MFC编译器不能产生可校验的代码

  三 C++/CLI给我们提供了什么?

   优雅流畅的语法和文法 C++/CLI为C++开发人员书写托管代码提供了一种非常自然的感觉 并且它提供了非托管代码到托管代码的平滑过度 以前所谓的 双重底线 问题现在已经荡然无存

   一流的CLI支持 CLI特色 例如属性 碎片集合和属类得到了直接支持 此外 C++/CLI还准许将这些特色用于本地非托管的类

   一流的C++类支持 C++特色 例如模板和析构函数对于拖管和非拖管类继续有效 实际上 C++/CLI是你可以 表面上 在栈或C++本地堆上声明一个 NET类型唯一的 NET语言

   在 NET与C++之间的沟壑上架起了一座桥梁 C++开发人员在抨击BCL时不再象离开水的鱼

   C++/CLI编译器产生的可执行文件完全是可校验的

  四 Hello World 小程序

  

   using namespace System; void _tmain() Console::WriteLine( Hello World );

  上述代码除了不需要引用mscorlib dll库外 与老的语法没有太大的区别 因为无论你什么时候使用/clr进行编辑 编译器都可以暗中进行引用(现在默认的是/clr:newSyntax)

  五 句柄

  与老的语法主要的混淆是我们习惯于使用*符号来声明拖管引用或非拖管指针 在C++/CLI里微软引入了句柄的概念

  

   void _tmain() //The ^ punctuator represents a handle String^ str = Hello World ; Console::WriteLine(str);

  ^符号代表一个托管对象(声明时看上去象个帽子) 按照CLI的规定 句柄代表一个拖管对象的引用 句柄在CLI中是新的语法 相当于C++中的 gc指针 句柄与指针不再混淆 在本质上两者完全不同

  六 句柄与指针是怎样区分开来的?

   指针声明时使用*符号 而句柄使用^符号

   句柄是针对拖管堆上对象的拖管引用 而指针仅仅指向内存中的一个地址

   指针很稳定 GC循环不会影响到它 句柄在基于GC或内存紧张的情况下 可以指向不同的内存位置

   对于指针 程序开发人员必须 显式 地删除 否则会面临泄露的危险 而对于句柄 是否进行显式删除则完全根据程序人员的爱好了

   句柄一定要指向一个具体的类型 即所谓的类型安全性 而指针明显不是这样 你决不可以将一个句柄指向Void^类型

   正如new操作符返回一个指针一样 gcnew返回一个句柄

  

  七 CLR对象示例

  

   void _tmain() String^ str = gcnew String( Hello World ); Object^ o = gcnew Object(); Console::WriteLine(str);

  关键字gcnew用来实例化一个CLI对象 而且它返回一个指向在CLR堆上的对象的句柄 gcnew的优点在于它可以方便的让我们区分拖管和非拖管的实例对象

  大部分情况下 gcnew关键字和^操作符提供了你用来进行BCL的一切手段 但是很明显你需要创建和声明属于自己的拖管类和接口

  八 声明类型

  CLR类型有一个形容词前缀用来说明类型的种类 下面是C++/CLI中的类型声明示例

  

   CLR types o Reference types § ref class RefClass ; § ref struct RefClass ; Value types § value class ValClass ; § value struct ValClass ; o Interfaces § interface class IType ; § interface struct IType ; o Enumerations § enum class Color ; § enum struct Color ; Native types o class Native ; o struct Native ; 示例 using namespace System; interface class IDog void Bark(); ; ref class Dog : IDog public: void Bark() Console::WriteLine( Bow wow wow ); ; void _tmain() Dog^ d = gcnew Dog(); d >Bark();

  上述程序中的代码与老的C++语言相比看上去非常简洁 在以往的C++代码中 至少要用到 gc和 interface这两个关键词

  九 装箱/拆箱操作

  在C++/CLI中 加箱是隐含的 而且类型是安全的 一个二进制的拷贝被执行并在CLR堆上形成一个对象 去箱是显式的 仅仅需要使用reinterpret_cast操作符来解除引用

  

   void _tmain() int z = ; Object^ o = z; //implicit boxing int y = *reinterpret_cast<int^>(o); //unboxing Console::WriteLine( o z y); z = ; Console::WriteLine( o z y); // 输出结果如下 // //

  在上述代码中 o 对象是一个加箱的拷贝 从第二个语句Console::WriteLine 的输出可以很明显地看到 它并没有涉及到int类型的整数值

  当你对一种数值类型进行加箱操作时 返回的对象记住了最初的数值类型

  

   void _tmain() int z = ; float f = ; Object^ o = z; Object^ o = f; Console::WriteLine(o >GetType()); Console::WriteLine(o >GetType()); // Output // System Int // System Single

  因此不能对不同类型的对象进行去箱操作

  

   void _tmain() int z = ; float f = ; Object^ o = z; Object^ o = f; int y = *reinterpret_cast<int^>(o );//System InvalidCastException float g = *reinterpret_cast<float^>(o );//System InvalidCastException

  如果你非尝试这么做 那么你将得到一个System InvalidCastException 让我们来探讨一下完美的类型安全性 如果你要看内部代码 你将看到微软的内部箱在实际中的运用 例如

  

   void Box () float y= ; Object^ o = y;

  编译后的代码是

  

   maxstack locals (float V_ object V_ ) ldnull stloc ldc r stloc ldloc box [mscorlib]System Single stloc ret

  根据微软的内部文档 箱操作将未加工的类型转换为一个具体类型的实例 这项工作的完成通过创建一个新的对象并将数据拷贝到这个新分配的对象

  十 写在后面的话

  为什么很多人已经可以使用C C++ NET来开发程序但还在积极学习C++/CLI呢 我想有四个方面的原因

   从编译器直到内层都还在支持C++代码

   C++/CLI对于其他标准来说无意是具有毁灭性地

   与生俱来的内部支持胜过所有其他CLI语言

cha138/Article/program/net/201311/11401

相关参考

知识大全 C++中,c_str()的用法

C++中,c_str()的用法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!C++中,c_str(

知识大全 C与C++中标准输入实现方式上的一点区别

C与C++中标准输入实现方式上的一点区别  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!刚开始学C语

知识大全 Java与C++

Java与C++  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java特别象C++由此很自然地

知识大全 我已经学了C语言,现在想学C++,请问哪位老师讲的好一些

我已经学了C语言,现在想学C++,请问哪位老师讲的好一些?  以下文字资料是由(本站网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 计算机二级中C语言、VB、VF、JAVA、Access、C++,有什么不同

计算机二级中C语言、VB、VF、JAVA、Access、C++,有什么不同?考哪一类别比较好?  以下文字资料是由(本站网www.cha138.com)小编为大家搜集整理

知识大全 C#与C++谁更强

C#与C++谁更强?还是关公战秦琼  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  我一直不明白C

知识大全 注意C++和C#引用的区别

注意C++和C#引用的区别  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  C#用多了最近又回到C

知识大全 java语言与c++相比,有哪些优点?

java语言与c++相比,有哪些优点?主要是这两种开发者对内存地址变量的不同理解,使两种语言在编程的思维上有所差异。C中存在指针变量,而且每个指针对应着一个真实的物理内存地址,他可以对相应地址中的内存

知识大全 计算机零基础想自学编程,C语言,C++ 要买哪些书,想自学好计算机,要学哪些基本课程啊

计算机零基础想自学编程,C语言,C++要买哪些书,想自学好计算机,要学哪些基本课程啊  以下文字资料是由(本站网www.cha138.com)小编为大家搜集整理后发布的内

知识大全 用Visual C++ 2005编写更快的代码

用VisualC++2005编写更快的代码  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  对于C