zoukankan      html  css  js  c++  java
  • 结构体与类

    1.什么是结构

      结构是程序员定义的数据类型,类似于类。它们都有数据成员和函数成员。

      区别就是:类是引用类型,结构是值类型

      结构是隐式封闭,不能被派生。 1 struct StructName 2 { 3 4 } 

    2.结构是值类型

      结构类型的变量不能为null

      两个结构变量不能引用同以对象

    3.对结构赋值

      对类赋值后CS2和CS1指向同一对象

      对结构赋值后,SS2和SS1成员的值相同

    4.结构函数和析构函数

      结构可以有实例构造函数和静态构造函数,但不允许有析构函数

      语言隐式的为每个结构提供一个无参数的构造函数:

        ①把每个成员设置为该类型的默认值。(值成员被设置成他们的默认值,引用成员被设置成null)

        ②预定义的无参数构造函数对每个结构都存在,而且不能删除或重定义。

        ③可以创建另外的构造函数,只要有参数。【区别:类】对于类编译器只在没有其他构造函数声明提供隐式无参数构造函数

        ④调用构造函数,需使用new运算符。即使不从堆中分配内存也使用new

        ⑤也可以不使用new运算符创建结构的实例,但是会有限制:不能使用数据成员的值,直到显式的设置它;不能调用任何函数成员,直到所有数据成员已经被赋值。

    5.静态构造函数

      【相似:类】结构的静态构造函数创建并初始化静态数据成员,而且不能引用实例成员。结构的静态函数构造遵从与类的静态构造函数一样的规则。

      静态构造函数在下面两个行为的第一个之前被调用

      ①调用显式声明的构造函数

      ②对结构静态成员的引用

    6.构造函数和析构函数的总结

    类型  描述
    实例构造函数(无参数) 不能在程序中声明。系统为所有结构提供一个隐式的构造函数,它不能被程序删除或重定义
    实例构造函数(有参数)  可以在程序中声明。
    静态构造函数 可以在程序中声明。
    析构函数 不能在程序中声明。析构函数不被允许

    7.字段初始化是不被允许的

      在结构中字段初始化是不允许的。

    8.结构是密封的

      结构总是隐式密封的,因此,不能从它们派生其他结构。

      由于结构不支持继承,个别类成员修饰符用在结构成员上将没有意义。因而,他们不能被用在结构成员声明中。不能用于结构的修饰符如下:

      protected

      internal

      abstract

      virtual

      结构本省派生自System.ValueType,System.ValueType派生object

      两个可以用于结构成员继承相关的关键字是new和override修饰符,当创建一个和基类System.ValueType的成员有相同名称的成员时使用它们。所有结构都派生自System.ValueType.

    9.装箱和取消装箱

      如同其他值类型数据,如果想使用一个结构实例作为引用类型,必须执行装箱的复制。装箱和装箱取消在后面的文章中会详述。

    10.结构可以作为返回值和参数

      返回值:当结构作为返回值时,一个复制被创建并从函数成员返回

      值参:当结构被用作值参时,一个实际参数的复制被创建。该复制被用在方法的执行中

      ref和out参数:如果把结构用作ref或out参数,一个对该结构的引用被传入方法,这样其数据成员就能被改变。

    11.关于结构的附加信息

      分配结构比创建类的实例需要更少的消耗,所以使用结构代替类有时可以提高性能,但要注意到装箱和取消装箱的高代价。

      预定义简单类型(int、short、long等)尽管在.NET和C#中被视为原始类型,它们实际上在.NET中都被实现为结构。

      可以使用声明partial类相同的方法声明partial结构

      结构就像类,可以实现接口。接口将在后面的文章中详述。

    12.[StructLayout(LayoutKind.Sequential)]在机构体前的声明

      首先[]表示标记语言标记绝大部分的作用是告诉IDE或者编译器 这个类 结构体 或者这个属性(不止是类可以加标记哦)有一些什么特别之处。

      结构体是由若干成员组成的.布局有两种
        1.Sequential,顺序布局,比如
      struct S1
      {
        int a;
        int b;
      }
      那么默认情况下在内存里是先排a,再排b
      也就是如果能取到a的地址,和b的地址,则相差一个int类型的长度,4字节
      [StructLayout(LayoutKind.Sequential)] 
      struct S1
      {
        int a;
        int b;
      }
      这样和上一个是一样的.因为默认的内存排列就是Sequential,也就是按成员的先后顺序排列.
      2.Explicit,精确布局
      需要用FieldOffset()设置每个成员的位置
      这样就可以实现类似c的公用体的功能
      [StructLayout(LayoutKind.Explicit)] 
      struct S1
      {
        [FieldOffset(0)]
        int a;
        [FieldOffset(0)]
        int b;
      }
      这样a和b在内存中地址相同

  • 相关阅读:
    Linux程序分析工具介绍—ldd,nm
    Makefile学习(三)[第二版]
    Linux下的tree命令 --Linux下目录树查看
    Makefile学习(二)[第二版]
    Makefile学习(一)[第二版]
    Linux下top命令详解
    Shell编程入门(第二版)(下)
    mysql用命令行导入sql文件
    javascript的onbeforeunload函数在IOS上运行
    mysql如何利用Navicat 导出和导入数据库
  • 原文地址:https://www.cnblogs.com/bigbear1385/p/5019472.html
Copyright © 2011-2022 走看看