Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 构造函数对对象的引用?_C#_.net_Class_Object_Stack - Fatal编程技术网

C# 构造函数对对象的引用?

C# 构造函数对对象的引用?,c#,.net,class,object,stack,C#,.net,Class,Object,Stack,正如我们所读到的,当为类创建对象时,比如MyClass MyClass=new MyClass()然后将创建实例,并将引用指针存储在堆栈内存中。如果类没有构造函数,那么将调用默认构造函数,然后说默认构造函数将返回指针。假设类有一个非参数化的构造函数,那么我的构造函数不会返回任何引用。然后从哪里返回引用的指针以及如何创建指针。简短回答:所有构造函数都返回已构造的对象 如果类没有构造函数,则使用默认构造函数 将被调用,然后说默认构造函数将返回 指针 你说得对。然而,您所称的“默认构造函数”实际上是一

正如我们所读到的,当为类创建对象时,比如
MyClass MyClass=new MyClass()
然后将创建实例,并将引用指针存储在堆栈内存中。如果类没有构造函数,那么将调用默认构造函数,然后说默认构造函数将返回指针。假设类有一个非参数化的构造函数,那么我的构造函数不会返回任何引用。然后从哪里返回引用的指针以及如何创建指针。

简短回答:所有构造函数都返回已构造的对象

如果类没有构造函数,则使用默认构造函数 将被调用,然后说默认构造函数将返回 指针

你说得对。然而,您所称的“默认构造函数”实际上是一个无参数构造函数,例如
publicmyclass()
。如果程序员没有编写一个,编译器会默认生成一个

以类具有非参数化构造函数为例,然后 我的构造函数不会返回任何引用


如果“非参数化构造函数”是指具有一个或多个参数的构造函数,例如
public MyClass(int arg)
,那么默认情况下编译器不会生成无参数构造函数。但是,编译器将确保您只调用已定义的构造函数。

指针不是来自构造函数。创建对象和执行构造函数是两种不同的操作

C语言规范(1.6.7.1)规定:

实例构造函数是实现操作的成员 需要初始化类的实例

因此,构造函数不会创建对象。相反,它初始化与对象关联的内存。在下面的简单示例中,创建由
CORINFO\u HELP\u 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\u HELP\u NEWFAST
,它创建了对象

随后是对构造函数的调用,构造函数初始化对象,但此时对象已被分配,我们有一个指向它的指针。构造函数不创建实例,而是初始化它


万斯·莫里森提供了更多详细信息

这不是一个非常准确的描述。如果一个类没有构造函数,它就不能被实例化。如果不在类定义中定义一个构造函数,编译器将为您生成一个空的默认构造函数(但某些类可能没有任何构造函数,例如静态类)。构造函数实际上并不返回引用。构造函数没有返回类型(它们隐式为void)。运行时是分配对象、调用构造函数并在构造函数返回后返回引用的对象。该引用从何而来?因为构造函数是类的入口点。可能这应该创建引用。不,
newobj
IL指令就是这样做的。它调用运行时在托管堆上分配内存。然后调用构造函数
newobj
使用元数据令牌来标识要使用的构造函数,因此它知道在分配内存后要调用什么。我认为这是最后一句话,但很难解析。@mjwills:我希望在理顺OP对前面几点的理解时,可以提出一个更好的问题。一、 我也不确定这个问题是什么,但它是基于不准确的语句,所以不管怎样,它是没有意义的。非参数化构造函数是一个零参数的构造函数。我总是读一个无参数的构造函数。不管怎样,我们谈论的是同一件事。现在你能告诉我你想知道更多关于构造函数的什么吗,因为我想我的答案是关于构造函数的基础知识。也许我错过了什么是的!这就是我要说的。