构造函数的对象引用?
Posted
技术标签:
【中文标题】构造函数的对象引用?【英文标题】:Object Reference by a constructor? 【发布时间】:2020-04-30 19:09:20 【问题描述】:正如我们所读到的,当为MyClass myClass = new MyClass();
之类的类创建对象时,将创建实例并将引用指针存储在堆栈内存中。如果该类没有构造函数,则将调用默认构造函数,然后说默认构造函数将返回指针。以类具有非参数化构造函数的情况为例,那么我的构造函数将不会返回任何引用。然后从哪里返回引用的指针以及如何创建它。
【问题讨论】:
这不是一个非常准确的描述。如果一个类没有构造函数,它就不能被实例化。如果您没有定义一个作为类定义的一部分,编译器将为您生成一个空的默认值(但某些类可能没有 任何构造函数,例如静态类)。构造函数实际上并不返回 reference。构造函数没有返回类型(它们是隐式无效的)。运行时是分配对象,调用构造函数,构造函数返回后返回引用。 @madreflection 该引用来自哪里?因为Constructor是Class的入口点。可能应该创建引用。 不,newobj
IL 指令就是这样做的。它调用运行时在托管堆上分配内存。 It 然后调用构造函数。 newobj
采用元数据标记,用于标识要使用的构造函数,因此它知道分配内存后要调用什么。
我已经读了几遍了,但无法弄清楚问题是什么。我认为它在最后一句中,但很难解析。
@mjwills:我希望在理顺 OP 对前面几点的理解时,可以提出一个更好的问题。我也不确定问题是什么,但它是基于不准确的陈述,所以无论如何它没有实际意义。
【参考方案1】:
简短回答:所有构造函数都返回已构造的对象。
如果类没有构造函数,则默认构造函数 将被调用,然后说默认构造函数将返回 指针。
你是对的。然而,您所说的“默认构造函数”实际上是一个无参数构造函数,例如public MyClass()
。如果程序员没有编写一个,编译器确实会生成一个默认。
假设类有一个非参数化的构造函数,那么 我的构造函数不会返回任何引用。
如果“非参数化构造函数”是指具有一个或多个参数的构造函数,例如public MyClass(int arg)
,则编译器默认不会生成无参数构造函数。但是,编译器会确保您只调用已定义的构造函数。
【讨论】:
非参数化构造函数是零参数的构造函数 我一直在阅读无参数构造函数。无论如何,我们谈论的是同一件事。现在你能告诉我你想了解更多关于构造函数的内容吗,因为我认为我的回答说明了它们的基本原理。或者也许我错过了什么【参考方案2】:指针不是来自构造函数。创建对象和执行构造函数是两个不同的动作。
C# 语言规范 (1.6.7.1) 规定:
实例构造函数是实现动作的成员 需要初始化一个类的实例
因此,构造函数不会创建对象。相反,它初始化与对象关联的内存。在下面的简单示例中,创建由CORINFO_HELP_NEWFAST
处理,但这只是下面链接的帖子所指出的创建对象的几种方法之一。
举一个像这样的简单程序来说明。
class Program
static void Main(string[] args)
var p = new Program();
Console.ReadLine();
Console.WriteLine(p.GetType());
public Program()
Console.WriteLine("ctor");
编译成下面的代码。
00760848 55 push ebp
00760849 8bec mov ebp,esp
0076084b 56 push esi
0076084c b9504d7100 mov ecx,714D50h (MT: ConsoleApp3.Program)
00760851 e87228faff call 007030c8 (JitHelp: CORINFO_HELP_NEWSFAST)
00760856 8bf0 mov esi,eax
00760858 8bce mov ecx,esi
0076085a ff15704d7100 call dword ptr ds:[714D70h] (ConsoleApp3.Program..ctor(), mdToken: 06000002)
00760860 e82bf32973 call mscorlib_ni+0xb8fb90 (739ffb90) (System.Console.ReadLine(), mdToken: 06000b6a)
00760865 8bce mov ecx,esi
00760867 e8d0f8ffff call 0076013c (System.Object.GetType(), mdToken: 0600022e)
0076086c 8bc8 mov ecx,eax
0076086e e88d1ead72 call mscorlib_ni+0x3c2700 (73232700) (System.Console.WriteLine(System.Object), mdToken: 06000b77)
00760873 5e pop esi
00760874 5d pop ebp
00760875 c3 ret
请注意,第一个操作是调用 CORINFO_HELP_NEWFAST
创建对象。
这之后是对初始化对象的构造函数的调用,但此时对象已被分配并且我们有一个指向它的指针。构造函数不创建实例,它初始化它。
万斯·莫里森here 提供了更多详细信息。
【讨论】:
是的!这就是我要说的。以上是关于构造函数的对象引用?的主要内容,如果未能解决你的问题,请参考以下文章