none
继承情况下,子类内存布局情况? RRS feed

  • 问题

  • 继承情况下,给子类分配的内存区域中包含从父类中继承的字段?还是子类内存中有一个指针指向父类的字段存储区?比较困惑,请指点!如果有图示意继承情况下,子类和父类的内存分配,那就更好了。看了一些资料,只看到讨论方法表,没有讨论继承情况下的字段存储。
    2012年9月28日 12:01

答案

  • 继承情况下,给子类分配的内存区域中包含从父类中继承的字段?还是子类内存中有一个指针指向父类的字段存储区?比较困惑,请指点!如果有图示意继承情况下,子类和父类的内存分配,那就更好了。看了一些资料,只看到讨论方法表,没有讨论继承情况下的字段存储。

    子类实例化的同时,父类中能够被继承的元素肯定都会被实例化一次。这就证明了继承情况下,子类沿袭了父类的存储空间,另外值得提醒的是,子类的实例化会导致父类任意变量都被实例化(无论是private还是其它的!)

    【证明】

    注意:其实A中的元素都被B继承了下来,只不过private不允许在B内部或者B实体的外部直接访问。你F5然后一步步F10,注意观察黄色光标棒的定位就明白了。(基类的所有成员(实例构造函数、析构函数和静态构造函数除外)都由派生类型继承。这甚至包括基类的私有成员。但是,私有成员的可访问域只包括声明该成员的类型的程序文本。

    同时进一步证明:

    namespace CSharp
    {
        public class A
        {
            private int i = 0;
    
            public void Change(B b)
            {
                b.i = 1;    //注意,是可以的!
            }
        }
    
        public class B:A
        {
           
        }
    }

    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年9月29日 8:07
    版主

全部回复

  • 内存布局(各个变量的顺序,以及字节对齐方式)在加载的时候决定,参考Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects


    Visual C++ MVP

    2012年9月29日 0:45
    版主
  • Sheng Jiang 蒋晟 :资料挺好的。但是没看到继承情况下,子类的具体字段存储啊?给子类分配的内存区域中包含从父类中继承的字段?还是子类内存中有一个指针指向父类的字段存储区?
    2012年9月29日 1:01
  • 给子类分配的内存区域中包含从父类中继承的字段,但是这个是实现细节,以后可能会更改。标准没规定类成员的内存布局。


    Visual C++ MVP

    2012年9月29日 1:04
    版主
  • 参考C# Language Specification Version 4.0 ,

    10.3.3 Inheritance

    An instance of a class contains a set of all instance fields declared in the class and its base classes,

    http://msdn.microsoft.com/en-us/library/ms228593(v=vs.100).aspx

    你可以用WINDBG 或者visual studio debugger 来证明。 

    2012年9月29日 6:07
  • 继承情况下,给子类分配的内存区域中包含从父类中继承的字段?还是子类内存中有一个指针指向父类的字段存储区?比较困惑,请指点!如果有图示意继承情况下,子类和父类的内存分配,那就更好了。看了一些资料,只看到讨论方法表,没有讨论继承情况下的字段存储。

    子类实例化的同时,父类中能够被继承的元素肯定都会被实例化一次。这就证明了继承情况下,子类沿袭了父类的存储空间,另外值得提醒的是,子类的实例化会导致父类任意变量都被实例化(无论是private还是其它的!)

    【证明】

    注意:其实A中的元素都被B继承了下来,只不过private不允许在B内部或者B实体的外部直接访问。你F5然后一步步F10,注意观察黄色光标棒的定位就明白了。(基类的所有成员(实例构造函数、析构函数和静态构造函数除外)都由派生类型继承。这甚至包括基类的私有成员。但是,私有成员的可访问域只包括声明该成员的类型的程序文本。

    同时进一步证明:

    namespace CSharp
    {
        public class A
        {
            private int i = 0;
    
            public void Change(B b)
            {
                b.i = 1;    //注意,是可以的!
            }
        }
    
        public class B:A
        {
           
        }
    }

    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年9月29日 8:07
    版主