面向对象之值传递和引用传递

来源:互联网 发布:dijkstra算法原理 编辑:程序博客网 时间:2024/05/19 12:26

对于值类型,常见有:int、double、float、bool、char等;
对于引用类型:数组、string、自定义类、接口等;
1、值类型复制就是,将原有的数据覆盖掉;
代码如下:

int i1=10int i2=i1;i2=20;Console.WriteLine(i2);

打印结果:20
我想上述的举例十分简单,但是他为面向对象的解释做一下对比;
2、我们知道,使用new关键字发生了三件事:1)开辟内存空间、2)创建对象、3)引用对象的构造函数进行初始化对象;
因此,在对类的实例化,我们会有些想法,类创建的对象放在栈中,而栈中存放对象指向堆中的地址,堆中存放对象的实例成员值;
以下我们通过一个例子解释:
1.创建类:

    public class Person    {        private string _name;        public string Name        {            get { return _name; }            set { _name = value; }        }    }

2.Main方法

            Person p1 = new Person();            p1.Name = "grenn";            Person p2 = p1;            p2.Name = "tom";            Console.WriteLine(p1.Name);

打印的结果:tom
按照一般常规思维,我们肯定认为打印出green,但是答案有些出人意料,因为我们忽视了栈空间,所以犯下了错误;以下我们用图解释:
这里写图片描述

其实,在Person p2=p1时,在栈中,他会将p1中的”指向堆地址空间”的值赋值给p2,在这里与值类型一样,但是赋值过后,p1,p2所指的堆空间地址是一样的,也就是说他们指向同一堆地址,因此,改变堆空间中值,他们都会改变;所以不管是p1还是p2的操作值变化,他们的值都会变;

3.但是还有一种情况是,string字符串,他在重新复制会重新开辟一个栈新地址和堆空间;如代码所示:

            string s = "hello";            string st = s;            st = "world";            Console.WriteLine(st);            Console.ReadKey();

打印结果:world

0 0