为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

C#与C++异同

2013-08-20 28页 pdf 454KB 30阅读

用户头像

is_343334

暂无简介

举报
C#与C++异同 C#与 C++异同 1 细微差异 ............................................................................................................................................................... 1 1.1 类的声明 .............................................................................
C#与C++异同
C#与 C++异同 1 细微差异 ............................................................................................................................................................... 1 1.1 类的声明 .................................................................................................................................................... 1 1.2 同名覆盖 .................................................................................................................................................... 1 2 多重继承 ............................................................................................................................................................... 1 3 C#虚和 C++中的虚 ................................................................................................................................. 3 4 数组 ....................................................................................................................................................................... 7 5 C#中按值传递和按引用传递 ................................................................................................................................. 7 6 字符串 ................................................................................................................................................................... 9 7 抽象类 ................................................................................................................................................................... 9 7.1 抽象类的构造函数................................................................................................................................... 11 8 C#类访问控制修饰符........................................................................................................................................... 13 9 C#中的类型转换 .................................................................................................................................................. 13 10 C#委托(delegate) ................................................................................................................................................ 14 11 C#中事件(event) ................................................................................................................................................. 17 12 接口(interface) ................................................................................................................................................... 19 12.1 接口的使用 ............................................................................................................................................ 19 12.2 接口的多继承 ........................................................................................................................................ 22 12.3 接口的重新实现..................................................................................................................................... 24 12.4 接口和多态 ............................................................................................................................................ 25 12.5 接口的应用举例..................................................................................................................................... 26 12.6 接口与抽象类的比较 ............................................................................................................................. 27 13 密封 ................................................................................................................................................................... 28 13.1 密封类 .................................................................................................................................................... 28 13.2 密封方法 ................................................................................................................................................ 28 1 细微差异 1.1 类的声明 C++的类声明结束后要在最后的大括号后面用分号结尾。C#则可用可不用,往往都是省略。 1.2 同名覆盖 C++中,如果基类和派生类有相同的成员,遵守同名覆盖原则,即派生类对象访问的是派生类的同名 成员,基类对象访问的是基类同名成员。 2 多重继承 C++可以多重继承,即一个派生类可以从多个基类同时继承,而 C#只能从一个类单重继承,但可以 通过接口实现多重继承。C++中如果基类和派生类中有相同成员时,遵循同名覆盖原则,即派生类对象使 用的是派生类同名成员,如果要在派生类中使用基类被覆盖的同名成员(称为派生类和基类互相通信)或 派生类外通过派生类对象访问基类同名成员,都必须使用基类名限定,如 A::f(),举例如下: Class A { Public: void f(){}; }; Class B:A { Public: void f() { A::f();//在派生类中访问基类成员 f(),互相通信 } }; 1 Void main() { A a; A *pa;//定义一个基类型指针 B b; pa=&b;//赋值兼容原则,基类指针可以指向派生类 a.f();//基类对象访问基类成员 f() b.f();//派生类对象访问类 B的 f() pa->f();//访问的是基类 A的 f() b.A::f();//派生类对象访问基类 A的 f() } 而 C#中在派生类访问基类被覆盖的同名成员时使用 base关键字来限定。C#还可以通过显式类型转 换来访问基类成员,如:((Parent)child).print(),其中 child 是派生类的对象,Parent 是基类名, 那么这个语句就是通过派生类对象访问基类成员。举例如下: using System; public class B0 { public void fb() //基类同名方法 { Console.WriteLine("B0's fb called!"); } } public class B1:B0 { public new void fb()//派生类同名方法,new示有意覆盖,若无会产生编译警告 { base.fb();//相互通信,派生类中访问基类方法 Console.WriteLine("B1's fb called!"); } } public class C { public static void Main() { B0 b0 = new B0(); b0.fb();//访问基类方法 B0 b1 = new B1();//基类型的引用指向派生类 b1.fb();//访问基类方法 B1 b2 = new B1(); b2.fb();//访问派生类方法 ((B0)b2).fb();//显式类型转换访问基类方法 Console.ReadLine(); } } 多态性就是指在程序运行时,执行的虽然是一个调用方法的语句,却可以根据派生类对象的类型不同 完成方法的不同的具体实现。在使用虚函数实现多态时,C++派生类覆盖基类虚函数时函数名前可写 virtual,也可以不写,默认为虚函数,在 C++中,由于基类和派生类的赋值兼容原则,可以定义一个基 类指针或引用指向派生类对象,那么通过该指针或引用访问的还是基类同名成员,除非把基类同名成员定 义成虚函数,那么基类指针或引用指向派生类对象访问的是派生类同名成员。上例代码修改如下: Class A { Public: Virtual void f(){};//f()定义成虚函数 }; Class B:A { Public: Virtual void f()//派生类 virtual关键字可省略,默认为虚函数 { 2 A::f();//在派生类中访问基类成员 f(),互相通信 } }; Void main() { A a; a.f();//基类对象访问基类成员 f() B b; b.f();//派生类对象访问类 B的 f() b.A::f();//派生类对象访问基类 A的 f() A *pa;//定义一个基类型指针 pa=&b;//赋值兼容原则,基类指针可以指向派生类 pa->f();//访问的是派生类 B的 f(),虚函数的作用 } C#派生类覆盖基类虚函数必须把基类虚函数 virtual 处写成 override,如:基类中虚函数 public virtual void f()那么派生类写成 public override void f()。上例修改如下: using System; public class B0//public可省略,默认为public访问修饰符 { public virtual void fb() //基类虚方法 { Console.WriteLine("B0's fb called!"); } } public class B1:B0 { public override void fb()//派生类覆盖虚方法 { base.fb();//相互通信,派生类中访问基类方法 Console.WriteLine("B1's fb called!"); } } public class C { public static void Main() { B0 b0 = new B0();//基类对象 b0.fb();//访问基类方法 B0 b1 = new B1();//基类型的引用指向派生类对象 b1.fb();//访问派生了类方法 B1 b2 = new B1();//派生类对象 b2.fb();//访问派生类方法 ((B0)b2).fb();//显式类型转换访问派生类方法 Console.ReadLine(); } } 3 C#虚方法和 C++中的虚函数 首先来观察 C++中的一段程序,如下: #include "iostream.h" class B0 { public: void f() {cout<<"B0.f"<f(); } void main() { B0 b0;//基类对象 B1 b1; B2 b2; b0=b1;//把派生类对象赋给基类对象,赋值兼容原则 b0.f();//输出 B0.f b1.f();//同名覆盖原则,输出 B1.f b2.f();//同名覆盖原则,输出 B2.f B0 *p;//基类型指针 p=&b1;//基类指针指向派生类,赋值兼容原则 fun(p); //因为是基类指针,所以输出 B0.f p=&b2; p->f();//因为是基类指针,所以输出 B0.f } 如果把上例中基类 B0的 f()函数写成虚函数,那么同样的main()运行结果不同,构成多态,修改如下: class B0 { public: virtual void f() {cout<<"B0.f"<f();//因为虚函数构成多态,所以输出 B2.f } 我们再来观察一段 C#程序,如下: class B0 { public void f() { Console.WriteLine("B0.f"); } } class B1:B0 { public void f() { 4 Console.WriteLine("B1.f"); } } class B2 : B1 { public void f() { Console.WriteLine("B2.f"); } } class Program { static void Main(string[] args) { B0 b0 = new B0();//基类对象 b0.f();//输出B0.f B0 b1 = new B1();//隐式类型转换 b1.f();//输出B0.f,和C++中类似。 B2 b2 = new B2();//派生类对象 b2.f();//输出B2.f Console.ReadLine(); } } 如果也把基类中的 f()函数写成虚方法,那么子类必须用 override覆盖 虚方法,构成多态,修改程序如下: class B0 { public virtual void f() { Console.WriteLine("B0.f"); } } class B1:B0 { public override void f() { Console.WriteLine("B1.f"); } } class B2 : B1 { public override void f() { Console.WriteLine("B2.f"); } } class Program { static void Main(string[] args) { B0 b0 = new B0();//基类对象 b0.f();//输出B0.f B0 b1 = new B1();//隐式类型转换 b1.f();//输出B1.f,由于是虚方法,和C++中类似。 B2 b2 = new B2();//派生类对象 b2.f();//输出B2.f Console.ReadLine(); } } 如果基类方法写成虚方法,可选择使用 override重写该方法,也可以选择使用 new不重写方法。 再写一个程序演示多态,如下: 5 class Employee { protected string name; public Employee() {} public Employee(string _name) { name = _name; } public virtual void StartWork() { Console.Write(name+"开始工作:"); } } class Manager:Employee { public Manager(string name):base(name) {} public override void StartWork() { base.StartWork(); Console.WriteLine("分配工作"); } } class Saler:Employee { public Saler(string name):base(name) {} public override void StartWork() { base.StartWork(); Console.WriteLine("推销产品"); } } class Technolgy : Employee { public Technolgy(string name) : base(name) { } public override void StartWork() { base.StartWork(); Console.WriteLine("技术开发"); } } class Program { static void Main(string[] args) { Employee[] emp=new Employee[3]; emp[0] = new Manager("张三"); emp[1] = new Saler("李四"); emp[2] = new Technolgy("王五"); foreach(Employee e in emp) { e.StartWork(); } Console.ReadLine(); } } 运行结果: 张三开始工作:分配工作 李四开始工作:推销产品 王五开始工作:技术开发 6 4 数组 在 C#中,数组实际上是对象。System.Array 是所有数组类型的抽象基类型。提供创建、操作、搜 索和排序数组的方法,因而在公共语言运行库中用作所有数组的基类。声明数组: int[] a=new int[5]; 可以同时初始化: int[] a=new int[5] {1,2,3,4,5}; 或 int[] a={1,2,3,4,5}; 举例如下: int[] a = new int[10] { 12,4,5,23,-5,21,3,0,-12,100}; for (int i = 0; i<10; i++) { Console.Write("{0} ",a[i]); } Array.Sort(a);//对数组进行排序 Array.Clear(a,0,10); //对数组元素置0 Array.Reverse(a); //对数组进行转置 for (int i = a.GetLowerBound(0); i <=a.GetUpperBound(0); i++)//数组的上下标 { Console.Write("{0} ", a[i]); } 5 C#中按值传递和按引用传递 C#中分为值类型变量和引用类型变量,传递值类型参数,可以通过值传递值类型参数,也可以通过 按引用传递值类型参数。 举例按值传递值类型参数如下: Class A {//本例没有实现交换数值的功能 static void swap(int x, int y)//按值传递 { int t; t = x; x = y; y = t; } Public statci void Main() { int a=3,b=5; swap(a,b);//只是传递 a,b的副本,不会改变实参值 Console.WriteLine("{0},{1}",a,b); } 结果:3,5 举例按引用传递值类型参数如下: Class A { static void swap(ref int x,ref int y)// {//按引用传递,调用函数前必须赋值 int t; t = x; x = y; y = t; } Public statci void Main() { int a=3,b=5; swap(ref a,ref b); //传递的不是 a,b的值,是对 a,b的引用,形参 x,y也不是 int类型,是对 int类型的引用 Console.WriteLine("{0},{1}",a,b); 7 } 结果:5,3 C#中引用类型变量不直接包含其数据,包含的是对数据的引用,引用类型数据也能按值传递和按引 用传递。 举例按值传递引用类型数据如下: class passingrefbyval { static void change(int[] arr) { arr[0]=888; // this change affects the original element. arr = new int[5] {-3, -1, -2, -3, -4}; // this change is local. console.writeline("inside the method, the first element is: {0}", arr[0]); } public static void main() { int[] myarray = {1,4,5}; console.writeline("inside main, before calling the method: {0}", myarray [0]); change(myarray); console.writeline("inside main, after calling the method: {0}", myarray [0]); } } 输出: inside main, before calling the method: 1 inside the method, the first element is: -3 inside main, after calling the method: 888 在此情况下,myarray 是一个指向数组的引用,将向方法传递指向 myarray 的引用的一个副本。 我们可以这么理解,一开始 myarray 是数组的引用,通过传递,使 arr 也称为数组的引用,那么这时候 myarrayh和 arr都是同一个数组的引用,所以 change方法中 arr[0]=888;语句改变了这个数组的第 一个元素值,但是 arr = new int[5] {-3, -1, -2, -3, -4};语句分配了新的内存空间,使 arr成为新的一个数组的 引用,所以接下来在 change方法中对 arr引用的数组的操作和myarray引用的数组无关,不会影响它 的值,其实在本例中创建了两个数组,一个在Main方法中,一个在 change方法中。 举例按引用传递引用类型数据如下: 本示例除在方法头和调用中使用 ref 关键字以外,其余和上例相同。 class passingrefbyval { static void change(ref int[] arr) { arr[0]=888; arr = new int[5] {-3, -1, -2, -3, -4}; console.writeline("inside the method, the first element is: {0}", arr[0]); } public static void main() { int[] myarray = {1,4,5}; console.writeline("inside main, before calling the method: {0}", myarray [0]); change(ref myarray); console.writeline("inside main, after calling the method: {0}", myarray [0]); } } 输出: inside main, before calling the method: 1 inside the method, the first element is: -3 inside main, after calling the method: -3 我们可以这么理解,由于是使用 ref 按引用传递,所以传递是引用 myarray 本身,也可以说 arr 就 是myarray,都是原始数组的引用,在 change方法中,有语句 arr = new int[5] {-3, -1, -2, -3, -4}; 8 使得 arr引用重新指向另一个数组,由于 arr就是myarray,所以此时myarray也指向另一个数组,所 以对 arr的操作就是对myarray的操作。 观察下面对于字符数组的交换: public class C { static void swap1(string x, string y)//按值传递 { string t; t = x; x = y; y = t; } static void swap2(ref string x, ref string y)//按引用传递 { string t; t = x; x = y; y = t; } public static void Main() { string s1="abc"; string s2="efg"; swap1(s1, s2); Console.WriteLine("{0},{1}",s1,s2); swap2(ref s1,ref s2); Console.WriteLine("{0},{1}",s1,s2); Console.ReadLine(); } } 输出: abc,efg efg,abc 6 字符串 C++处理字符串,可以使用字符数组、string类或指针来操作。如下: char c1[]=”hello!”; char c2[10]; string s1,s2; s2=c1; cin>>s1; cin>>c2; cout<
/
本文档为【C#与C++异同】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索