从编译角度看对象访问控制
关于卢彦的"protected的Quiz"我想在这里再写点什么。尽管一直想写个“闲聊面向对象程序”系列文章,但总没有抽出足够的时间,所以先半截腰谈谈我对面向对象的认识。
面向对象绝对是一个不好学的课程,李维的《深入核心VCL架构剖析》给了我不少启示。面向对象之所以具有继承、封装、多态等特征,其本质与VTM (Virtual Method Table)有直接关系。而不同语言编译器在实现上采用的技术也各不相同。下面是某系统的一个对象在内存中的布局
Offset What
+0 Pointer to VMT.
+4 Data. All fields in the order the've been declared.
...
今天不讨论VTM,先说说Data。假设有如下两个类
class Base
...{
private
int m=2;
}
class Child : Base
...{
private
int m=1;
}
它们经过编译后,执行以下两条命令:
Base b = new Base();
Child c = new Child();
形成的内存结构(猜测,希望大家多指正)如下(图里省略了VTM,仅仅关注数据部分,下同):
由图中我们可以看到,c中包含了两个m(没错,所有父类的字段,不管是私有还是公有都会在子类中得到继承),一个是继承下来的,一个是自身的m。只不过从存取权限上讲,c只能存取自己的那个m,而无法访问父类继承的那个m。
然后我们再来讨论安全性问题。C#语言为我们提供了private、public、protected三种访问控制符,关于它们的区别就不用我多说了。就我的感觉,对象的每一个方法、字段、属性都具有一个安全上下文,当这个对象试图访问另外一个对象的内容时,需要出示自己的安全上下文,在被允许的情况下才可以访问
详细的可以看这里:http://www.netcsharp.cn/showtopic-364.aspx