zoukankan      html  css  js  c++  java
  • 堆栈和堆问题

     

    昨天做题的时候发现自己又有点弄不太懂堆栈和堆的问题了,就是值类型和引用类型的东西了。

    就是昨天晚上挑灯研究了下,总结点内容希望对其他人有点用。

     

    堆和堆栈的问题

    值是存在于堆上的。引用是栈上的。值的实例在栈上,引用的对象在堆上。 值类型是把值赋予另一个,a=b,把b的值给a之后a和b没有关系了。 引用这相反。所以值类型改变原来a值b则不会改变值。

    值类型的实例经常会存储在栈上的。但是也有特殊情况。如果某个类的实例有个值类型的字段, 那么实际上该字段会和实例保存在一个地方,即堆栈中。不过引用类型的对象总是存储在堆中。 如果一个结构字段是引用类型,那么只有引用本身是和结构实例存储在一起的(或堆或栈上,视情况而定)。

    1,结构是值类型,类是引用类型  

    注:a,值类型在堆栈上分配地址,引用类型在堆上分配地址(堆栈的执行效率比堆高,但是堆栈的资源有限,适用于简单的逻辑                 处理,如:基本类型中int 对应的 system.Int32等都是结构)           b,值类型的赋值可以创造新的值类型,而引用类型之间的赋值是复制引用的地址           c,结构和类的基类都是object,c#所有的类型的基类都是object           d,虽然结构的初始化也使用了New 操作符可是结构对象依然分配在堆栈上而不是堆上,如果不使用new,那么在初始化所有                 字段之前,字段将保持未赋值状态,且对象不可用  

    2, 结构(struct)不能从另外一个结构或者类继承,本身也不能被继承,虽然结构没有明确的用sealed声明,可是结构是隐式的sealed       类(class)完全可扩展的,除非显示的声明sealed 否则类可以继承其他类和接口,自身也能被继承 

    注:结构可以使用和类相同的办法继承接口(有点奇怪)  

    3,和类相比,结构没有默认的构造函数,但可以添加构造函数,没有析构函数,因为不能继承,所以没有abstruct和sealed 不能用proteced修饰, 并且可以不用new初始化,结构中不能初始化字段。  

    下面是一个类和结构的例子:  

    struct SPerson{      

            //public SPerson(){}//Error:结构不能包含显式的无参数构造函数      

    public SPerson(string name,int age)      

    {           this.name=name;                   this.age=age;

          }      

    //public int =2; //Error:类、结构或接口成员声明中的标记“=”无效      

    private string name;     

      private int age;      

    public string Name{get{return name;}set{name=value;}}      

    public int Age{get{return age;}set{this.age=value;}}      

    public override string ToString(){          

           return string.Format("Struct:Name:{0},Age:{1}",this.name,this.age);      

                }   }   class CPerson{  

        public CPerson(){}           

      public CPerson(string name,int age){         

              this.name=name;           this.age=age;  

                }           

      private string name;      

    private int age;     

    public string Name{get{return name;}set{name=value;}}  

    public int Age{get{return age;}set{age=value;}}            

    public override string ToString()

    {         

      return string.Format("Class:Name:{0},Age:{1}",this.name,this.age);    

       }   }  

    public class MyClass{  

    public static void Main()      

    {         

      CPerson cp1=new CPerson("Zhang San",23);          

    SPerson sp1=new SPerson("Zhang San",23);                   

      Console.WriteLine("First Class:cp1:"+cp1.ToString());                 

      //输出:First Class:cp1:Name:Zhang San,Age:23  

    Console.WriteLine("First Struct: sp1:"+sp1.ToString());        

       //输出:First Struct: sp1:Name:Zhang San,Age:23  

      CPerson cp2=cp1;//cp2引用cp1         

      SPerson sp2=sp1;//cp2的值为cp1内的值   

      Console.WriteLine("Second Class:cp2:"+cp2.ToString());                    

      //输出:Second Class:cp2:Name:Zhang San,Age:23  

    Console.WriteLine("Second Struct: sp2:"+sp2.ToString());          

    //输出:Second Struct: sp2:Name:Zhang San,Age:23  

         Console.ReadKey();     

        Console.WriteLine("Change First Class And Struct:");  

                    //改变值:          

    cp1.Name="Wang Wu";        

    cp1.Age=100;          

    sp1.Name="Wang Wu";     

    sp1.Age=100;  

            Console.WriteLine("Afte Change first Class cp1:"+cp1.ToString());                  

          //输出:Afte Change first Class cp1: cp1:Name:Wang Wu,Age:100  

            Console.WriteLine("Afte Change first Struct sp1:"+sp1.ToString());             

          //输出:Afte Change first Struct sp1:Name:Wang Wu,Age:100  

            Console.WriteLine("Afte Change First Class, Second Class cp2:"+cp2.ToString());                  

         //输出:Afte Change First Class, Second Class cp2:Name:Wang Wu,Age:100  

      //------------------------------------------------------------------------------------------------------------    

    //值类型:           Console.WriteLine("Afte Change First Struct, Second Struct sp2:"+sp2.ToString());                  

      //输出:AAfte Change First Struct, Second Struct sp2:Name:Zhang San,Age:23    

    //-------------------------------------------------------------------------------------------------------------  

            Console.ReadKey();            }   }

    1.struct 是值类型,class 是对象类型

    2.struct 不能被继承,class 可以被继承

    3.struct 默认的访问权限是public,而class 默认的访问权限是private.

    4.struct总是有默认的构造函数,即使是重载默认构造函数仍然会保留。这是因为Struct的构造函数是由编译器自动生成的,但是如果重载构造函数,必需对struct中的变量全部初始化。并且Struct的用途是那些描述轻量级的对象,例如Line,Point等,并且效率比较高。class在没有重载构造函数时有默认的无参数构造函数,但是一被重载些默认构造函数将被覆盖。

    5.struct的new和class的new是不同的。struct的new就是执行一下构造函数创建一个新实例再对所有的字段进行Copy。而class则是在堆上分配一块内存然后再执行构造函数,struct的内存并不是在new的时候分配的,而是在定义的时候分配

  • 相关阅读:
    openjudge 2750
    hexo部署云服务器
    freemaker传输数据问题
    FormData在axios中的骚操作
    Docker安装与初次使用
    docker-compose实现前后端分离的自动化部署
    centos7下设置静态ip
    centos7 安装mariadb 并配置主从复制
    centos7安装solr服务
    centos7安装redis
  • 原文地址:https://www.cnblogs.com/kounian/p/3382997.html
Copyright © 2011-2022 走看看