构造函数的对象引用?

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 提供了更多详细信息。

【讨论】:

是的!这就是我要说的。

以上是关于构造函数的对象引用?的主要内容,如果未能解决你的问题,请参考以下文章

拷贝构造函数

拷贝构造函数调用的三种情况

Excel VBA 对象构造函数和析构函数

拷贝构造函数详解

拷贝构造函数详解

javascript之构造函数的继承(引用网络)