c++与c#的一些不同(一) 实例化

来源:互联网 发布:阿里云数据库连接2003 编辑:程序博客网 时间:2024/06/03 17:54

最近学习了一段时间设计模式,慢慢意识到继承与组合,接口,多态的重要作用,因此又准备学习一下这方面理论知识,但是c++与c#有一些不同,时刻困扰着我,缠不清楚的感觉让人不舒服,于是自己总结了一下。

首先是类的实例化

c++中声明了 一个类的对象后 没有用类似于 C# 或 Java中的new 来实例化(刚开始我很费解),先看c#,类型按下图分类

C#的所有值类型均隐式派生自System.ValueType:

  • 结构体:struct(直接派生于System.ValueType);
    • 数值类型:
      • 整 型:sbyte(System.SByte的别名),short(System.Int16),int(System.Int32),long (System.Int64),byte(System.Byte),ushort(System.UInt16),uint (System.UInt32),ulong(System.UInt64),char(System.Char);
      • 浮点型:float(System.Single),double(System.Double);
      • 用于财务计算的高精度decimal型:decimal(System.Decimal)。
    • bool型:bool(System.Boolean的别名);
    • 用户定义的结构体(派生于System.ValueType)。
  • 枚举:enum(派生于System.Enum);
  • 可空类型(派生于System.Nullable<T>泛型结构体,T?实际上是System.Nullable<T>的别名)。

值类型(Value Type),值类型实例通常分配在线程的栈(stack)上,并且不包含任何指向实例数据的指针,因为变量本身就包含了其实例数据

C#有以下一些引用类型:

  • 数组(派生于System.Array)
  • 用户用定义的以下类型:
    • 类:class(派生于System.Object);
    • 接口:interface(接口不是一个“东西”,所以不存在派生于何处的问题。Anders在《C# Programming Language》中说,接口只是表示一种约定[contract]);
    • 委托:delegate(派生于System.Delegate)。
  • object(System.Object的别名);
  • 字符串:string(System.String的别名)。

可以看出:

  • 引用类型与值类型相同的是,结构体也可以实现接口;
  • 引用类型可以派生出新的类型,而值类型不能;
  • 引用类型可以包含null值,值类型不能(可空类型功能允许将 null 赋给值类型);
  • 引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值,也就是堆上保存着实例化对象,栈上保存着引用。

再看看,c++

我找资料发现c++中累的实例化有两种

A a;

A * a = new a();

以上两种方式皆可实现类的实例化,有new的区别在于:

1.前者在堆栈中分配内存,后者为动态内存分配,在一般应用中是没有什么区别的,但动态内存分配会使对象的可控性增强。

2.不加new在堆栈中分配内存

3.大程序用new,小程序直接申请

4.只是把对象分配在堆栈内存中

5.new必须delete删除,不用new系统会自动回收内存

看完第一点,大家应该明白了,其不同之处就在于c++与c#的栈不同,再考虑深层次原因,由于c#(java也类似,用的java虚拟机)程序是CLR负责垃圾的释放,栈操作只需要函数执行完就可以,它里面不存在所谓的垃圾,因此所谓的垃圾主要是指堆中内容,由于CLR有一套自己的回收机制,因此只要是稍微大一点的实例化对象就都放在了堆里,这样便于管理。c++不同,他需要用户手动释放,所以只要不是用户主动申请的,都必须放在栈里,才能够自动释放,除非用户主动申请,才把实例化对象放在堆里,这样用户也必须手动delete。