浅谈对象的内存分配及对象的成员的访问(一)

假设有如下的一个类:
class Test
{
  public int id;
  private uint age;
  public string name;
  public Test() {}
  …
}
采用 Test test = new Test() 来创建一个对象,我们来看看这句话怎么在内存中体现呢?
一般来讲我们将内存分为堆栈区、堆区和局部变量区,今天我们只讨论堆栈和堆,如图:

再来看Test test = new Test() 这句话在内存中的体现,首先我们可以将这句话拆成下面的两句:
Test test; //创建一个Test类型的变量
test = new Test(); //给这个变量赋值
       我们先看第二句代码,所谓的new关键字实际上就是通知编译器在堆区为其分配内存空间,至于分配在哪个地方,我们是不知道的,只不过编译器分配完内存后会给你一个地址,我们以后就通过这个地址来访问编译器分配的内存的内容,就像你的朋友在一个城市买了房,它买房子的时候可能根据具体的情况会选在城市的任何地方,但是它只需要给你一个他的房子的地址你就一定能找到它的家,而且还可以去他的房子里面玩他的游戏机。还有个问题就是这个new分配了多大的内存呢,这个问题跟我们的类的成员的类型有关系,以后再讨论这个问题。
        这个时候我们的内存分配图就发生了变化,在堆中多出了一块已经分配好的内存,假设他的地址是10000001,其中还有类的成员id, age, name都在这块内存中找到了地方安家,并且他们都拥有自己的地址,就像你朋友的家,买好了房子,那么家具家电都能放进去了,而且各自都有自己的位置,目前的内存分布图变成:

但是还有个问题,堆中分配好的内存地址谁来保管呢?就像朋友的房子的地址你是需要知道的啊,如果没有人知道这个地址,麻烦那就大了,就像没有你朋友的房子的地址,你是很难找到它的家的。这个时候一直沉默不语的test变量说话了,放我这里吧,哈哈,我这里空着呢,于是我们就在test变量中保存了编译器在堆上面分配的内存地址,但是这个地址应该放在堆区还是堆栈区呢,这个时候熟悉内存地址的朋友应该都知道,所谓的内存的地址只不过是一个十六进制的数,那么这样的数,在C#中我们将它们称为值类型,那么我们就知道了,原来test应该存放在堆栈区,占用多大地方呢,一个整型类型的大小4个字节,于是内存的分布图就变成了下面的样子:

通过上面这个图,我们就很好理解我们对于类的成员字段的访问方式了?
test.id实际上就是通过访问test变量中保存的堆中内存的地址来直接访问堆中的变量的值,通俗点讲就是你通过test中保存的你朋友的房子的地址找到城市中的他的家,然后通过 . 操作找到你想要玩的游戏机,你有没有发现 . 就像是一个查找游戏机地址的操作呢,所以我还是私下的喜欢把 . 操作符称之为内存的寻址操作,就像C++中的 -->操作符一样。
但也不是所有的成员都能够通过 . 操作符访问到,就像上面用private修饰的成员,他表示私有的,是不允许你访问的。
上面主要讨论了对象的非静态成员字段在内存中的分配,其实类的成员还有另一个重要的部分,那么成员方法在内存中怎么分配呢,这个我们下次再来讨论 ^_^   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值