A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马王楠 初级黑马   /  2012-9-18 08:47  /  1562 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

麻烦多说说

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

7 个回复

倒序浏览
1. Class可以被实例化,属于引用类型,是分配在内存的堆上的。
2. Struct属于值类型,是分配在内存的栈上的。结构体是复制传递的。

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
结构是值类型:值类型在堆栈上分配地址,任何的基类型(基本类型,不是基类)都是结构类型,例如:int 对应System.int32 结构,通过使用结构能够创建更多的值类型
类是引用类型:引用类型在堆上分配地址
堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑
因为结构是值类型所以结构之间的赋值能够创建新的结构,而类是引用类型,类之间的赋值只是复制引用。
结构:不能从另外一个结构或类继承,本身也不能被继承,虽然结构没有明确的用sealed声明,可是结构是隐式的sealed .
类:完全可扩展的,除非显示的声明sealed 否则类能够继承其他类和接口,自身也能被继承
注:虽然结构不能被继承 可是结构能够继承接口,方法和类继承接口相同
例如:结构实现接口
interface IImage

{
void Paint();
}

struct Picture : IImage
{
public void Paint()
{
// painting code goes here
}
private int x, y, z; // other struct members
}

内部结构:
结构:
没有默认的构造函数,但是能够添加构造函数
没有析构函数
没有 abstract 和 sealed(因为不能继承)
不能有protected 修饰符
能够不使用new 初始化
在结构中初始化实例字段是错误的
类:
有默认的构造函数
有析构函数
能够使用 abstract 和 sealed
有protected 修饰符
必须使用new 初始化 。

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

回复 使用道具 举报
这个问题我也是在网上找的资料,不过感觉最全面的分析还是在这个网站,有时间去看看吧http://www.cnblogs.com/sbxwylt/articles/1402539.html

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

回复 使用道具 举报
类:
类是引用类型在堆上分配,类的实例进行赋值只是复制了引用,都指向同一段实际对象分配的内存
类有构造和析构函数
类可以继承和被继承
结构:
结构是值类型在栈上分配(虽然栈的访问速度比较堆要快,但栈的资源有限放),结构的赋值将分配产生一个新的对象。
结构没有构造函数,但可以添加。结构没有析构函数
结构不可以继承自另一个结构或被继承,但和类一样可以继承自接口

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

回复 使用道具 举报
结构是一种将有关数据打包到一起的机制,类似于数据库中的一条记录,相对于松散的数据是一种进步。但是结构并不能完善的表达面向对象的思想,他只能描述对象的性质如姓名,年龄等而无法描述对象的行为如行走,说话。而类则可以包含这些特征,也就是常说的类中可以包含成员变量(对象的性质)和成员函数(对象的行为)。此外,类还具有继承和多态的属性,实现了对象的繁衍。

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

回复 使用道具 举报
类:

类是引用类型在堆上分配,类的实例进行赋值只是复制了引用,都指向同一段实际对象分配的内存

类有构造和析构函数

类可以继承和被继承

结构:

结构是值类型在栈上分配(虽然栈的访问速度比较堆要快,但栈的资源有限放),结构的赋值将分配产生一个新的对象。

结构没有构造函数,但可以添加。结构没有析构函数

结构不可以继承自另一个结构或被继承,但和类一样可以继承自接口


示例:

根据以上比较,我们可以得出一些轻量级的对象最好使用结构,但数据量大或有复杂处理逻辑对象最好使用类。

如:Geoemtry(GIS 里的一个概论,在 OGC 标准里有定义) 最好使用类,而 Geometry 中点的成员最好使用结构

using System;
using System.Collections.Generic;
using System.Text;

namespace Example16
{
    interface IPoint
     {
        double X
         {
             get;
             set;
         }
        double Y
         {
             get;
             set;
         }
        double Z
         {
             get;
             set;
         }
     }
    //结构也可以从接口继承
    struct Point: IPoint
     {
        private double x, y, z;
        //结构也可以增加构造函数
        public Point(double X, double Y, double Z)
         {
            this.x = X;
            this.y = Y;
            this.z = Z;
         }
        public double X
         {
             get { return x; }
             set { x = value; }
         }
        public double Y
         {
             get { return x; }
             set { x = value; }
         }
        public double Z
         {
             get { return x; }
             set { x = value; }
         }
     }
    //在此简化了点状Geometry的设计,实际产品中还包含Project(坐标变换)等复杂操作
    class PointGeometry
     {
        private Point value;
        
        public PointGeometry(double X, double Y, double Z)
         {
            value = new Point(X, Y, Z);
         }
        public PointGeometry(Point value)
         {
            //结构的赋值将分配新的内存
            this.value = value;
         }
        public double X
         {
             get { return value.X; }
             set { this.value.X = value; }
         }
        public double Y
         {
             get { return value.Y; }
             set { this.value.Y = value; }
         }
        public double Z
        {
             get { return value.Z; }
             set { this.value.Z = value; }
         }
        public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth)
         {
            return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z);
         }
        public override string ToString()
         {
            return string.Format("X: {0}, Y: {1}, Z: {2}", value.X, value.Y, value.Z);
         }
     }
    class Program
     {
        static void Main(string[] args)
         {
             Point tmpPoint = new Point(1, 2, 3);

             PointGeometry tmpPG1 = new PointGeometry(tmpPoint);
             PointGeometry tmpPG2 = new PointGeometry(tmpPoint);
             tmpPG2.X = 4;
             tmpPG2.Y = 5;
             tmpPG2.Z = 6;

            //由于结构是值类型,tmpPG1 和 tmpPG2 的坐标并不一样
             Console.WriteLine(tmpPG1);
             Console.WriteLine(tmpPG2);

            //由于类是引用类型,对tmpPG1坐标修改后影响到了tmpPG3
             PointGeometry tmpPG3 = tmpPG1;
             tmpPG1.X = 7;
             tmpPG1.Y = 8;
             tmpPG1.Z = 9;
             Console.WriteLine(tmpPG1);
             Console.WriteLine(tmpPG3);

             Console.ReadLine();
         }
     }
}

结果:
X: 1, Y: 2, Z: 3
X: 4, Y: 5, Z: 6
X: 7, Y: 8, Z: 9
X: 7, Y: 8, Z: 9

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

回复 使用道具 举报
结构与类很相似,都表示可以包含数据成员和函数成员的数据结构。与类不同的是,结构是值类型并且不需要堆分配。结构类型的变量直接包含结构的数据,而类类型的变量包含对数据的引用(该变量称为对象)。
结构可以声明构造函数,但它们必须带参数。声明结构的默认(无参数)构造函数是错误的。总是提供默认构造函数以将结构成员初始化为它们的默认值。在结构中初始化实例字段是错误的。在类中,必须初始化实例对象. 使用 new 运算符创建结构对象时,将创建该结构对象,并且调用适当的构造函数。与类不同的是,结构的实例化可以不使用 new 运算符。如果不使用 new,那么在初始化所有字段之前,字段将保持未赋值状态且对象不可用。对于结构,不像类那样存在继承。一个结构不能从另一个结构或类继承,而且不能作为一个类的基。但是,结构从基类 Object 继承。
结构可实现接口,其方式同类完全一样。
一个是值类型(结构),一个是引用类型(类),结构在传递的时候如果没有指定ref,则传递的是内存中的一分副本,而class则是传递对他的引用。
类在堆中,结构在栈中,类传递的是类在堆中的地址,而结构是在栈中另复制了一个传递,你改变传递过来的结构不会影响原结构。而类是引用,共用一块内存,会改变堆中类的内容.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马