zoukankan      html  css  js  c++  java
  • C#与C++的区别(二)

    这几天深入学习C#的面向对象的内容,发现C#的很多用法跟C++比起来还是有很多的不同点,头脑中知识的海洋刮起了阵阵海浪,在此继续整理一下二者的不同点,主要还是写的C#能用,而在C++中不能用的一些知识。(以下都是C#的用法)

    1.类的构造函数

    可通过初始值设定项来调用基类的构造函数,例如:
    public Student(string no,string name,char sex,int age):base(name,sex,age)
    {......}
    这是调用父类的用法;

    类的构造函数也可以通过关键字this调用同一个类的另一个构造函数,例如:

    public Point():this(0,20)
    {......}
    其中this先执行,而point的大括号内的代码后执行


    2.私有构造函数

    在某些特殊的情况下,使用私有构造函数能够表达意想不到的效果。比如,想建立这样一个类,不允许被对象实例化,但提供对外的静态接口成员;

    public class filling
    {
    	private filling(){};//私有构造
    	public static void happy()
    	{
    		Console.WriteLine("Happy!");
    	}
    	public static void sad()
    	{
    		Console.WriteLine("Sad!");
    	}
    }
    public class MainClass
    {
    	public static void Main()
    	{
    		//filling f1=new filling();//不能实例化
    		filling.happy();
    		filling.sad();
    		
    	}
    }

    3.析构函数

    C#支持析构函数。虽然C#能够自动进行垃圾回收,但对于某些资源,.Net不知道如何回收,所以需要人工的内存回收。

    • 托管资源 ,如简单的int,string,float,DataTime等等,是不需要人工进行回收的
    • 非托管资源,例如文件,窗口或网络连接
    .(1)NET Framework提供Obeject.Finalize方法,在默认情况下,Finalize不执行任何操作,有需要的话可以覆盖

    通过析构函数可以自动生成对Finalize方法和对基类的Finalize方法的调用。


    但是需要注意的是:如果试图既编写析构函数,又编写Finalize方法的话,将导致编译器报错。

    (2)实现非托管资源的释放回收时,采用Dispose()方法

    • 实现Dispose()方法时,一定要加上"GC.SuppressFinalize(this)"语句。作用是抑制析构函数的执行。

    /*
     * Created by SharpDevelop.
     * User: tianyu
     * Date: 2017/9/16
     * Time: 10:43
     * 
     * To change this template use Tools | Options | Coding | Edit Standard Headers.
     */
    using System;
    
    
    
    
    
    
    	public interface IDisposable
    	{
    		void dispose();
    	}
    	
    	
    	
    	class myFile:IDisposable
    	{
    		public myFile(){}
    		public void close(){}
    		public void dispose()
    		{
    			close();
    			Console.WriteLine("Close");
    			//GC.SuppressFinalize(this);
    			
    		}
    		~myFile()
    		{
    			Console.WriteLine("Deconstructor");
    		}
    	}
    	class Program
    	{
    		public static void Main(string[] args)
    		{
    			myFile file=new myFile();
    			file.dispose();
    			Console.ReadLine();
    		}
    	}
    

    体验一下把
    GC.SuppressFinalize(this);
    注释掉和不注释的结果


    4.静态方法

    类方法是不需要类的任何实例都可以被调用的方法,在方法生命中用static关键字表示,通过类名调用。

    注意:类方法只能访问静态变量,访问非静态变量的尝试会引起编译错误。


    5.静态构造函数(感觉这个贼好玩)

    特别注意的是:静态构造函数只会执行一次,而且是在类中第一个对象初始化或者是引用任何静态成员之前执行。

    所有C#中没有全局变量,要想实现全局变量相同的功能,可以在类内定义一个静态变量,然后通过“类名.静态变量”的形式调用。静态变量只有在执行完以后才会回收。

    静态构造函数的典型用途是:

    当类使用日志文件时,将使用这种构造函数向日志文件中写入项。

    /*
     * Created by SharpDevelop.
     * User: tianyu
     * Date: 2017/9/16
     * Time: 11:02
     * 
     * To change this template use Tools | Options | Coding | Edit Standard Headers.
     */
    using System;
    
    namespace static_contrutor
    {
    	class  Student
    	{
    		public int serialNum;
    		private static int counter;
    		static Student()//静态构造函数
    		{
    			Random rand=new Random();
    			counter=rand.Next(0,1000);
    			Console.WriteLine("static Contructor={0}",counter);
    		}
    		public Student()
    		{
    			serialNum=counter;
    			counter++;
    			Console.WriteLine("Constructor");
    		}
    	}
    	class Program
    	{
    		public static void Main(string[] args)
    		{
    			Student s=new Student();
    			Console.WriteLine("{0}",s.serialNum);
    			Student s1=new Student();
    			Console.WriteLine("{0}",s1.serialNum);
    			Console.ReadLine();
    		}
    	}
    }


    6.类的字段成员——只读字段

    当字段声明中包括readonly修饰符时,该字段成为只读字段。只能在声明只读字段的时候赋予初值。其他任何时候都不允许为只读字段赋值。


    但是,如果在类定义中的时候显式的添加一个构造函数,可以在构造函数中改变只读字段的值。

    using System;
    
    namespace readOnly
    {
    	class Program
    	{
    		public readonly string str1="i am str";
    		public Program()
    		{
    			str1="i am not str";
    		}
    		public static void Main(string[] args)
    		{
    			Program p=new Program();
    			Console.WriteLine(p.str1);
    			Console.ReadLine();
    		}
    	}
    }

    7.类的方法成员--静态方法

    使用static静态字来修饰。静态方法不需要类实例,直接使用“类名.方法”格式调用即可;

    注意:在静态方法体内不能够直接使用非静态成员,也没有this引用,因为没有实例可以引用。

    public class operat
    	{
    		public long add(long a,long b)
    		{
    			return a+b;
    			
    		}
    		public double add(double a,double b)//重载
    		{
    			return a+b;
    			
    		}
    		public static void hi()
    		{
    			Console.WriteLine("hi");
    			//add(3,5);不能再静态函数体内访问非静态成员
    		}
    	}
    	//可以再Main函数体内访问operat.hi(),因为Main函数本身就是静态函数

    8.参数传递--主要思考地址传递(ref和out)

    对于初学者来说,ref和out经常分不清各自的功能,于是我整理了一波二者的区别:

    • 使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。(代码出区别)
    class RefExample
    {
        static void Method(ref int i)
        {
            i = 44;
        }
     
        static void Main()
        {
            int val = 0;
            Method(ref val);
            // val is now 44
        }
    }


    class OutExample
    {
        static void Method(out int i)
        {
            i = 44;
        }
     
        static void Main()
        {
            int value;
            Method(out value);
            // value is now 44
        }
    }
    using System;
    class Program
    {
    static void Main()
    {
        Program obj = new Program();
        int score = 55; //声明原来分数
        int refscore, outscore; //声明两个变量
        obj.ChangeScore(score, ref refscore, out outscore);
        Console.WriteLine("您原来的分数是{0},调整后的分数为{1},加平时表现分后{2}",
          score, refscore, outscore);
        Console.ReadKey();
    }
    private void ChangeScore(int score, ref int refscore, out int outscore)
    {
        if (score > 50 && score < 60)
        {
          refscore = 60;
        }
        if (refscore > 60)
        {
          outscore = refscore + 5;
        }
    }
    }


    • 使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。
    • out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。
    • ref是    有进有出,而out是       只出不进。

    9.参数数组

    在不确定需要传递多少个参数的时候使用params关键字指明一个可变的参数数组。数组参数的类型必须是一维数组,而且是形参表上的最后一个参数,对于值类型,数组参数是值传递方式进行传递,且不能用ref或out与params进行组合。

    namespace param
    {
    	
    	class Program
    	{
    		public static double averge(params int[]nums)
    	{
    		int sum=0;
    		int cnt=0;
    		foreach(int i in nums)
    		{
    			sum+=i;
    			cnt++;
    		}
    		return (sum/cnt);
    	}
    		public static void Main(string[] args)
    		{
    			double d=averge(13,13,16,27);
    			Console.WriteLine("average={0}",d);
    			Console.ReadLine();
    	
    		}
    	}
    }

    10.属性成员

    属性主要用于描述和维护类对象的状态。对属性的访问就好像是直接访问public字段的成员,但在类内部是通过类方法访问的。

    创建一个属性包括两步:

    • 声明一个字段来存储属性值
    • 编写一个属性·声明,提供一个访问接口
    class Program
    	{
    		private string propVal;
    		public string str//声明属性str
    		{
    			get//返回存在私有变量的属性值
    			{
    				return propVal;
    			}
    			set//存储属性值到私有变量
    			{
    				propVal=value;
    			}
    		}

    可以说,属性是一种特殊的方法,但是属性和方法还是有不同之处:

    • 属性不用使用圆括号,但方法一定要有圆括号
    • 属性不能指定参数,但是方法可以指定参数
    • 属性不能使用void类型,方法介意使用void类型
    • 属性使用方法和变量相同

    11.索引器

    参数成员属性:set、get方法

    与成员属性不同:

    它可以接受1个或多个参数

    使用this关键字作为索引器的名字

    namespace photo
    {
    	class Photo
    	{
    		string title;
    		public Photo(string title)
    		{
    			this.title=title;
    		}
    		public string Title
    		{
    			get
    			{
    				return title;
    			}
    		}
    		
    	}
    	class Album
    	{
    		Photo []photo;
    		public Album(int capacity)
    		{
    			photo=new Photo[capacity];
    		}
    		public Photo this[int Index]//带有int参数的索引
    		{
    			get
    			{
    				if(Index<0||Index>=photo.Length)
    				{
    					Console.WriteLine("索引无效");
    					return null;
    				}
    				return photo[Index];
    			}
    			set
    			{
    				if(Index<0||Index>=photo.Length)
    				{
    					Console.WriteLine("索引无效");
    					return;
    					       
    				}
    				photo[Index]=value;
    			}
    		}
    		public Photo this[string str]
    		{
    			get
    			{
    				foreach(Photo p in photo)
    				{
    					if(p.Title==str)
    						return p;
    				}
    				Console.WriteLine("未找到");
    				return null;
    			}
    		}
    		
    	}
    }












  • 相关阅读:
    JSP根据身份证号码计算生日
    JSP听课笔记(二)
    JSP听课笔记(一)
    JDBC连接数据库过程(转载)
    PL/SQL
    阅读笔记
    javaScript的一些奇妙动画
    原型与原型链之间一些奥秘
    CSS3 @keyframes 规则
    Java语言中的基本词汇
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9387216.html
Copyright © 2011-2022 走看看