堆栈和堆问题

 

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

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

 

堆和堆栈的问题

值是存在于堆上的。引用是栈上的。值的实例在栈上,引用的对象在堆上。 值类型是把值赋予另一个,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的时候分配的,而是在定义的时候分配

posted @ 2013-10-22 19:30  勿念  阅读(278)  评论(0编辑  收藏  举报