gpt4 book ai didi

oop - 这个对象初始化会发生什么?

转载 作者:行者123 更新时间:2023-12-04 07:01:06 24 4
gpt4 key购买 nike

我按照下面的代码进行了对象初始化:

namespace PatternPractice
{
public class TestClass
{
private DecoratorClass decoratorClass;
public TestClass()
{

}

public void addTest()
{
decoratorClass = new DecoratorClass();
testMethod(decoratorClass);
}

public void testMethod(DecoratorClass d)
{
Console.WriteLine("Am doing to explain my question.");
}
}
}

我有以下问题:

一种。什么是装饰类变量?对创建此变量的内存位置的引用,还是其他什么?

湾在 addTest() 方法中,我初始化了这个装饰器类,它现在变成了什么,是对对象的引用,还是其他什么?

C。如果这成为对对象的引用,那么我们为什么要在要通过引用传递的参数中使用 ref 。如果decoratorClass 不是引用和其他东西,这个问题就不成立了。

d.在 testMethod() 方法中,我知道创建并传递了 decoratorClass 的副本,它是引用还是其他什么?

我对这一切是如何在运行时(ASP.NET 或 JVM 等)结束时发生的有点困惑,基本上与内存中的对象创建有关。

是否有任何文章可以解释运行时如何创建对象以及它们如何分配到内存。

谢谢您的帮助。

最佳答案

值类型和引用类型的基本概念。

任何类型的变量(无论是值类型还是引用类型),在声明时都会被压入堆栈。

但是,它们之间的区别在于,在值类型的情况下,对象的值存储在堆栈中。而在引用类型的情况下,堆的地址存储在堆栈中。

因此,请考虑以下语句:

int a;
DecoratorClass decoratorClass;

现在当这些语句运行时,这是堆栈:
STACK:

Variable Value
a 0 // Since ints are assigned to 0 by default
decoratorClass NULL

现在,如果您尝试访问decoratorClass,例如 decoratorClass.memberVariable = xyz;等等,那么你会得到一个 NullPointerException。
这是因为,decoratorClass 只是声明未初始化。只有当你调用构造函数时它才会被初始化。

所以当下面的语句运行时:
decoratorClass = new DecoratorClass();

1)内存在特定位置(地址)的堆上分配。以字节为单位分配的内存量取决于类定义(成员变量)
HEAP:

xEEEE00
xEEEE01
xEEEE02
xEEEE03

2)现在由于一些内存分配给对象,堆栈将使用内存地址更新
STACK:

Variable Value
a 0 // Since ints are assigned to 0 by default
decoratorClass xEEEE00

现在,如果您尝试访问decoratorClass.memberVariable,您将不会收到NullPointer 异常,因为实例已初始化且内存位置已在堆栈上分配。

现在回答您的问题:

一种。 什么是装饰类变量?对创建此变量的内存位置的引用,还是其他什么?

在 addTest() 方法中,我初始化了这个装饰器类,它现在变成了什么,是对对象的引用,还是其他什么?

答案:
当声明语句运行时,decoratorClass 变量将被压入堆栈。
由于尚未在堆上分配内存,因此堆栈上的值(应该是堆上的地址)将为空。
调用构造函数时将在堆上分配内存。
堆栈现在将包含堆上的地址

让我在回答 c 之前先回答 d,因为我相信这样你会更容易理解。

d. 在 testMethod() 方法中,我知道创建并传递了 decoratorClass 的副本,它是引用还是其他什么?

答案:
根据我上面给出的解释,在方法 testMethod(DecoratorClass d) 中,d 是 testMethod() 的局部变量。但是 d 中的值是什么(即堆栈上的值)?它是decoratorClass的地址。所以局部变量 d 指向同一个堆,因此访问 d 的 memberVariable 将给出与访问 decoratorClass 的 memberVariable 相同的值。

现在,如果您创建一个新的 DecoratorClass 并将其分配给 d,它不会更改decoratorClass。所以d可能指向EEEE06,但decoratorClass仍会指向EEEE00。

现在让我们转到 c。

C。 如果这成为对对象的引用,那么我们为什么要在要通过引用传递的参数中使用 ref 。如果decoratorClass 不是引用和其他东西,这个问题就不成立了。
答案:
让我们考虑相同的方法 testMethod(ref DecoratorClass d)。由于您将 d 作为 ref 传递,因此它不再是局部变量,而是同一个变量。

现在,如果您创建一个新的 DecoratorClass 并将其分配给 d,它将会改变decoratorClass。所以 d 将指向 EEEE06,但会产生 DecoratorClass 也指向 EEEE06 的效果,因为两者都是堆栈上的相同变量。

有关按引用传递对象与按值传递对象的更多详细信息,请查看 Memory games

希望我说得够详细了。

干杯!

关于oop - 这个对象初始化会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1818973/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com