3

我想知道当我们创建派生类的实例时,基类是如何在派生类之前自动实例化的。

我只想知道基类的成员如何占用内存,子类的引用如何访问它们。

4

3 回答 3

3

让我们举一些例子:

class A
{
    int x;
    int y;
}

class B: A
{
    int c;
}

如果创建 的新实例A,则会在堆上创建一块内存。该内存将占用 8 个字节;4 个字节x和 4 个字节y。(我知道,为它的类型保留了更多的内存,等等,但我会把它留在这个范围之外)。

如果您创建 的新实例B,则会创建另一块内存。不是两个,只有一个。所以没有子实例或任何东西。这块内存的长度为 12 个字节(4 个字节用于x, 4 个字节用于 , 4y个字节用于新字段z

当在堆上创建一块内存时,它总是会被零填充。因此,在这种情况下,所有字段都将具有其默认值0

如果两个类都有一个公共的无参数构造函数,这些构造函数会被自动调用。

class A
{
    int x;
    int y;
    public A()
    {
        x = 1; y = 2;     
    }
}

class B: A
{
    int c;
    public B()
    {
        z = 3;
    }
}

当一个新的实例B被创建时,构造函数B被调用。构造函数做的第一件事就是调用构造函数AA将设置其字段xy12。然后程序返回到B谁将z使用该值进行初始化的构造函数3

的构造函数B也可以写成(以表明它B正在调用其 base 的构造函数A):

    public B()
        : base()
    {
        z = 3;
    }
于 2013-05-09T09:16:06.003 回答
2

对象是一次性创建的:字段的空间是根据需要为,中X : Y : Z声明的字段总和(以及任何开销,作为 的隐含基础)所需空间的知识分配的。字段是继承的,所以an.XYZobjectZX Z

它们是自下而上初始化的,因为这是构造函数的工作方式;如果我们写:

class A : B
{
    private int _a = 1;
    public A() { Console.WriteLine("A"); }
}
class B {
    private int _b = 1;
    public B() { Console.WriteLine("B"); }
}

然后我们得到(对于B):

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldc.i4.1 
    L_0002: stfld int32 B::_b
    L_0007: ldarg.0 
    L_0008: call instance void [mscorlib]System.Object::.ctor()
    L_000d: ldstr "B"
    L_0012: call void [mscorlib]System.Console::WriteLine(string)
    L_0017: ret 
}

A

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldc.i4.1 
    L_0002: stfld int32 A::_a
    L_0007: ldarg.0 
    L_0008: call instance void B::.ctor()
    L_000d: ldstr "A"
    L_0012: call void [mscorlib]System.Console::WriteLine(string)
    L_0017: ret 
}

请注意,它在运行自己的本地构造函数代码之前调用基本构造函数。另请注意,字段初始化器甚至在此之前出现。

于 2013-05-09T09:14:52.670 回答
0

对此的一个简单解释是将继承视为复制机

所以让我们定义2个类

class Base
{
}

class Child : Base
{
}

现在您要创建一个子对象。Child 有自己的字段,但由于它从基类继承,它必须去复制其基类的所有字段,因此会自动创建。

类是对象的模板,继承只不过是可以在创建新模板时附加的可重复使用的模板。

于 2013-05-09T09:18:26.113 回答