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;
}
}
}
}
C#与C++的区别(二)的更多相关文章
- C#中抽象类和接口的区别(二)
一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外 ...
- Python协程与Go协程的区别二
写在前面 世界是复杂的,每一种思想都是为了解决某些现实问题而简化成的模型,想解决就得先面对,面对就需要选择角度,角度决定了模型的质量, 喜欢此UP主汤质看本质的哲学科普,其中简洁又不失细节的介绍了人类 ...
- vue1.0和vue2.0的区别(二)
这篇我们继续之前的vue1.0和vue2.0的区别(一)继续说 四.循环 学过vue的同学应该知道vue1.0是不能添加重复数据的,否则它会报错,想让它重复添加也不是不可以,不过需要定义别的东西 而v ...
- Linux内存管理--虚拟地址、逻辑地址、线性地址和物理地址的区别(二)【转】
本文转载自:http://blog.csdn.net/yusiguyuan/article/details/9668363 这篇文章中介绍了四个名词的概念,下面针对四个地址的转换进行分析 CPU将一个 ...
- java集合对象区别二
集合包是Java中最常用的包,它最常用的有Collection和Map两个接口的实现类,Collection用于存放多个单对象,Map用于存放Key-Value形式的键值对. Collection中常 ...
- OC与Swift的区别二(常量、变量、运算符)
4.常量与变量声明 oc的变量声明使用 类型 变量名 = 变量值的方式,其中类型为系统内置数据类型或自定义类型,变量名需由英文字母开头且不能包含特殊字符 swift变量声明使用 var 变量名 = ...
- 传统IO与NIO区别二
nio是new io的简称,从jdk1.4就被引入了.现在的jdk已经到了1.6了,可以说不是什么新东西了.但其中的一些思想值得我来研究.这两天,我研究了下其中的套接字部分,有一些心得,在此分享. ...
- Cocos2d中update与fixedUpdate的区别(二)
关于update:方法的目的 update:方法的目的在于给你一个更新你的游戏(你游戏中的所有对象,标签等待)的机会,在它们被渲染到屏幕之前. 换句话说,如果你想要一些游戏对象显示在屏幕的特定位置,你 ...
- C++与C的区别二
1. new,delete的局部重载: #include <iostream> using namespace std; ; class myclass { public: myclass ...
- java static成员变量方法和非static成员变量方法的区别 ( 二 )
原创文章,未经作者允许,禁止转载!!! 静态成员变量不用new对象,在类加载的过程中就已经初始化存放在数据区域,静态成员变量是类和所有对象共有的,类和对象都可以改变它的值,每一次改变值之后,静态成员变 ...
随机推荐
- [bzoj4519][Cqoi2016]不同的最小割_网络流_最小割_最小割树
不同的最小割 bzoj-4519 Cqoi-2016 题目大意:题目链接. 注释:略. 想法: 我们发现这和最小割那题比较像. 我们依然通过那个题说的办法一样,构建最小割树即可. 接下来就是随便怎么处 ...
- 常见Unix指令
常用的UNIX指令: 1.文件和目录操作 ls –l 列出当前目录下的所有内容(文件\文件夹) pwd 显示出当前目录的名称 cd 改变当前操作的目录 who 显示当前用户名 clear ...
- Spring Boot-Logback 配置(区分环境、分包、分级别打印)
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!--生产环境 - ...
- Servlet实现点击计数器
以下内容引用自http://wiki.jikexueyuan.com/project/servlet/hits-counter.html: 一.Web页面的点击计数器 很多时候,可能有兴趣知道网站的某 ...
- Linux纯Shell实现DNSPod动态域名
http://www.anrip.com/post/872 开发背景: 公司有台嵌入式拨号上网设备,内置busybox和完整wget命令(支持https协议),但没有curl.python.ruby. ...
- MapReduce的Reduce side Join
1. 简单介绍 reduce side join是全部join中用时最长的一种join,可是这样的方法可以适用内连接.left外连接.right外连接.full外连接和反连接等全部的join方式.r ...
- Java内存问题的一些见解
在Java中,内存泄露和其它内存相关问题在性能和可扩展性方面表现的最为突出.我们有充分的理由去具体地讨论他们. Java内存模型--或者更确切的说垃圾回收器--已经攻克了很多内存问题. 然而同一时候, ...
- CodeIgniter RestServer中put请求获取不到參数的问题解决
近期用restserver遇到个蛋疼的问题,发现$this->put得到的參数都是null.查了一下发现.这貌似这个普遍问题,參见链接:https://github.com/chriskacer ...
- TQ2440 学习笔记—— 1、Windows平台下开发工具安装与环境建立
板子:广州天嵌公司的TQ2440,处理器为三星的S3C2440 1.开发工具的安装与环境建立 系统:win7 64位 SecureCRT软件:该软件能够取代Windows中的超级终端,是个非常好的串 ...
- ios23--动画做弹出提示框toast
) { /* [UIView animateWithDuration:2.0 animations:^{ // 执行动画 self.showHUB.text = @"当前购物车已空,赶紧买买 ...