摘 要:C#是微软公司伴随其. NET战略推出的一种全新语言,是一种先进的,面向对象的开发语言,能够方便快捷地建立基于微软网络平台的各种应用和在网络间互相调用的WEB服务。C#可以更好地帮助开发人员避免错误,提高工作效率,同时具备C++的强大功能。C#与C++都是面向对象的语言,因此类在这两种语言中都有非常重要的地位。本文,我将对比C++和C#中的类,并着重说明微软在C#类中引入的新特性。 关键词:C# C++ 类 面向对象
1 新一代开发语言C#
作为微软的网络服务平台.NET战略的重要组成部分,微软推出了一种命名为C#(发音为C Sharp)的新开发语言。C#是一种先进的、面向对象的语言,通过它可以帮助开发人员快速建立大范围的基于网络平台的应用,并且提供大量的开发工具和服务帮助开发人员实现各种基于计算和通信的企业级应用程序。
由于C#是一种功能强大的面向对象的开发语言,所以C#既可以广泛适用于高层商业应用,也可以适用于底层系统的开发。通过C#内置的强大功能可以方便地开发各种组件,将传统的应用转变为基于网络的应用,并且能够通过互连网与其它语言开发的各种系统集成,或是作为服务被其他开发语言所开发的应用调用。因此C#在微软.NET框架中占有非常重要的地位。
对于数量众多的C++程序员来说,C#是他们过渡到网络计算环境的最佳选择。因为C#是以C++为基础,并吸收了当今优秀的开发语言的特点而形成的新语言。它既保留了C++效率高、功能强大的优点,又吸收了其他语言(如JAVA、VB)的快速开发、网络计算等优点,具有自己独特的优势。熟悉C++的程序员再学习C#将是一个非常容易的过程,熟悉JAVA的程序员也可以比较快速的学习C#。由于C#与C++都是面向对象的语言,因此类在这两种语言中都是一个非常重要的概念,也是学习过程中的一个重点。本文将对C++和C#的类作一些比较,并着重说明微软在C#类中引入的新特性。
2 C#类与C++类的对比
C#语法风格源自C++,所以C++程序员学习C#代码不会感到很困难。C#代码中的类定义和类实现代码都包含在同一文件模块中,不再有像C++那样的全局函数。在C++中,程序员可以显式地创建构造函数,拷贝构造函数,重载操作符,使用模板等等。而在C#中,微软力求使类本身的定义更加灵活而减少程序员使用方面的麻烦。大部分C++特性在C#中都有对应,但编写代码却更加容易。
我们可以先观察一下C#类中都存在哪些类成员。类成员包含类本身声明的成员以及继承自直接基类的成员。类成员可分为以下几种:
常量——实现与类相关的常数值 字段——实现类中的变量
方法——实现类可以执行的计算和
操作
属性——定义命名标志以及读取写入这些标志的操作
事件——定义可以由类产生的通告 索引器——允许类实例可以采用与数组的同样的方式被索引
运算符——定义可对类实例使用的表达式运算符
实例构造函数——实现初始化类实例所需的操作
静态构造函数——实现了初始化类本身所需的操作
析构函数——实现了销毁类实例前所需的操作
类型——定义类中的局部类型
从C#中可以应用的类成员中可以看出,C#中除了保留C++的类成员外还进行了扩展,引入了诸如属性、事件等新的成员。按照类成员以及类的声明和使用,本文将对C#类与C++类作一比较。
2.1 类声明
(1) 在C++中使用xxx.h头文件来声明类,在xxx.cpp文件中实现类的代码,在需要引用类定义的地方使用#include语句包含相应的头文件。在C#中则借鉴了JAVA的做法,类的声明与实现代码被放在同一文件xxx.cs中,取消了头文件以减少程序维护的困难。
(2) 在C++中必须保证类名称互不冲突,否则将引起编译错误。在C#中引入命名空间分层次命名的概念,只要求同一命名空间中的类名不冲突。
(3) 在C++中类声明结束后需要在最后的大括号后面用分号结尾。在C#中则可用可不用,往往会省略。
(4) 在C++中没有针对类本身的访问修饰符。C#对此了改变,可以附加类访问修饰符来限制对类实例的访问权。C#设定8个类访问修饰符:
公有(public)——可以被所有其它的类访问 私有(private)——只有类成员才能访问 保护(protected)——只有类成员和继承类成员可以访问 内部(internal)——只有同一模块内部的成员才能访问 内部保护(protected internal)——只有同一模块内部的类成员和继承类
成员可以访问 密封(sealed)——类不能再继承。无论直接或间接地将它作为基类,C#
编译器都会跳错 抽象(abstract)——与C++的虚类或虚方法(virtual)相似,抽象类不能直
接实例化,抽象函数含有函数名但在作为基类或继承类时可以使用。 新建(new)——用new创建嵌套类,可以隐藏继承方式,告诉编译器
创建一个类的新版本。 2.2 程序入口
在C++中,全局函数main()(dos平台)或WinMain()(Windows平台)作为所有程序的入口点。C#中取消了像C++那样的全局函数,而选择了在类中定义唯一的静态函数Main()。Main()函数在C#里非常特殊,它是编译器规定的所有可执行程序的入口点。Main()函数必须为静态函数(static),这允许C#不必创建实例对象即可运行程序,一个C#程序中只能有一个Main()函数入口点。C#是大小写敏感的语言,所以Main()函数名的第一个字母要大写,否则将不具有入口点的语义。
2.3 实例化 在C++中,类的实例化——对象既可以声明为栈变量在堆栈上分配,也可以使用new操作符在堆中分配。在C#中,对象不可以分配在堆栈中,要创建类实例,必须用new关键字分配在托管堆上。分配在托管堆中的对象无须程序员调用delete语句显式清除,.NET平台的自动垃圾收集机制减轻了程序员内存管理的负担。
2.4 封装性
C++中定义了三种类成员访问级别: 私有(private)——只有类成员才能访问
保护(protected)——只有类成员和继承类成员可以访问 公有(public)——可以被其他类或函数访问 C#中扩展了两种类成员访问级别:
内部(internal)——只有同一模块内部的成员才能访问
内部保护(protected internal)——只有同一模块内部类成员和继承类成员可以访问
2.5 继承性
继承是面向对象语言的核心特征之一。在C++中既支持单继承也支持多重继承。而在C#中取消了类多重继承的概念,多重继承仅允许在接口实现中使用,目的是为了减少代码维护的复杂性,提高代码的重用率。
2.6 多态性
在C++和C#中处理多态性是很相像的。C++使用纯虚函数和虚函数实现运行时的多态性。在C#中引入了virtual,override,sealed,abstract四种修饰符来实现不同的多态性,使代码更加直观。并且在C#中组合使用sealed和override关键字来实现在派生类中停止覆盖虚方法。
2.7 “装箱”与“开箱”
C++中的值类型都是在堆栈中分配。由于在C#中引入了统一类型系统的概念,通过“装箱”(Boxing)与“开箱”(Unboxing)操作,任何类型的值都可以变成对象来操作。“装箱”(Boxing)操作把一个值“装箱”从而隐式地把一个值类型转换成对象类型。“开箱”(Unboxing)操作是将对象类型显式转换为某一类型值的操作。当然,基于执行效率这种转换只是在需要转换时才进行。
2.8 方法
方法是类功能的实现部分。C++的成员方法可以接收值参数、引用参数、指针参数以及变长参数序列。C#改进了C++中的方法参数,包括:输入参数、引用参数、输出参数和参数序列。其中对象只能作为引用参数,而不能作为值参数传递。输入参数类似于C++中的值参数,但在使用前需要初始化。C#中抛弃了指针的概念,利用输出参数可以想调用函数返回多个值,输出参数在使用前不需要初始化。参数序列与C++中类似,可以接收可变个数的参数值,但必须位于参数表的末尾。
2.9 属性
通过借鉴VB、DELPHI等快速开发语言的优点,C#语言也引入了类属性的概念。程序员既可以通过字段也通过属性来访问类的数据成员。字段是作为具有公共访问性的成员变量而被实现的;属性与字段不同的不同之处在于:后者不代表存储位置,而是通过与属性对应的存取函数实现对属性值的获取或设置。当你想读出或写入属性的值时,存取标志限定了被实现的语句。用于读出属性的值的存取标志记为关键字get,而要修改属性的值的存取标志记为set。通过使用属性,可以使类中定义的数据成员更加安全,防止外部无限制的访问或因为疏忽而造成的数据破坏。C++中没有实现类属性。
2.10 数组
在C#中,数组对象共同的基类是System.Array。因此,虽然在C#中定义数组的语法格式与C++或Java中类似,但定义数组实际上是实例化了一个System. Array类,即声明的每一个数组都从System.Array类中继承了相同的成员,可以很方便地应用其中实现的方法。C#除了一维数组以外,还支持多维数组。而在C++中数组只是相同类型值或对象的组成的连续存储区,只能通过索引访问而无类方法的支持。
2.11 索引器
所谓索引器就是一类特殊的属性,通过它们你就可以像引用数组一样引用自己的类。C#通过提供索引器,可以象处理数组一样处理对象。显然,这一功能在创建集合类的场合特别有用,而在其他某些情况下,比如处理大型文件或者抽象某些有限资源等,能让类具有类似数组的行为当然也是非常有用的。C++中无索引器的概念。
2.12 代表
代表可以被认为是类型安全的、面向对象的函数指针,它可以拥有多个方法。代表处理的问题在C++中可以用函数指针处理,而在Java中则可以用接口处理。它通过提供类型安全和支持多方法改进了函数指针方式;它通过可以进行方法调用而不需要内部类适配器或额外的代码去处理多方法调用问题而改进了接口方式。代表最重要用途是事件处理。
2.13 事件
事件是对象从外部世界获取的通告.它允许对象执行与之相关联的操作。C#提供了对事件的直接支持。C#使用delegate和event关键字提供了一个清楚的事件处理方案。事件既可以被声明为类的域成员,也可以被声明为属性。每一个事件都可以被0个或更多的客户关联,且客户可以随时关联或取消事件。你既可以用静态方法定义代表,也可以用实例方法定义代表。C++中采用指向回调函数的指针来支持事件,比较复杂。
2.14 特性
C#和Java的编译代码里都包括类似于字段访问级别的信息。C#扩展了这个能力,对类中的任何元素,比如类、方法、字段甚至是独立参数,你都可以编译自定义的信息,并可以于运行时获取这些信息。C#通过特性提供了这样一种机制,就是在设计时可以用信息来对类型和成员进行注释,并且可以在运行时通过反射(reflection)来获取这些信息。这使您可以真正创建自我包含的、自我描述的组件,而不必借助于向一些资源文件或注册表写入一些必需的注册信息。这样有利于编写出更简单、更易于维护、移植性更强的组件。C++中无特性的概念。
2.15 接口
因为C#并不支持多继承,所以接口在C#的开发中起着特殊的作用。为了共享语义上相关的方法和属性,类可以实现多个接口。C#的另一个强大的功能就是能够把两个或以上的接口合并到一起,这样一个类只要实现合并后的接口就可以了。C++则通过多继承或嵌套类来实现接口。
3 结束语
C#语法风格源自C++,融合了Visual Basic、JAVA的高效和C++强大,是微软为奠定其下一互联网霸主地位而打造的Microsoft.Net平台的主流语言。使用C#,你就能创建任何应用:Windows应用,控制台应用,Web应用和Web服务等等。所有的.NET平台使用的语言都编译成为中间语言(IL),并能按照系统环境
进行优化。相对于C++,用C# 开发应用软件可以大大缩短开发周期,同时可以利用原来除用户界面代码之外的C++代码。通过比较C#和C++中的类,我们可以发现二者既有很多相似之处,同时C#又对C++进行了许多扩展,结果是功能更加强大。C++程序员学习C#将会有一条比较平缓的学习曲线,同时也可以比较容易地将C++程序转换成C#程序。未来几年,C# 将不可避免地崛起,在Windows平台上成为真正的主角。