为什么有可能在没有新关键字的情况下实例化一个结构体?
为什么我们不会强制实例化一个结构,就像使用类时一样?
原因很简单 - 因为规范是这样说的 。 如何确保整个内存块是“明确分配”的,这意味着:为结构的每个字段分配一个值。 但是,这需要2件讨厌的事情:
所以在大多数最佳实践情况下,您确实需要使用new(...)
语法来正确调用构造函数(或为零参数构造函数调零)。
为什么我们不需要用“new”实例化一个结构,就像使用类时一样?
当你“新”参考类型时,会发生三件事。 首先,内存管理器从长期存储中分配空间。 其次,将该空间的引用传递给构造函数,该构造函数初始化实例。 第三,该引用被传回给调用者。
当你“新”一个值类型时,会发生三件事。 首先,内存管理器从短期存储中分配空间。 其次,构造函数被传递给短期存储位置的引用。 构造函数运行后,短期存储位置中的值将被复制到值的存储位置,无论这种情况发生在哪里。 请记住,值类型的变量存储实际值。
(注意,如果编译器可以确定这样做从不将部分构造的结构暴露给用户代码,那么编译器可以将这三个步骤优化为一个步骤,也就是说,编译器可以生成简单地将引用传递给最终的代码存储位置到构造函数,从而节省一个分配和一个副本。)
所以现在我们可以解决你的问题,你实际上已经向后询问。 最好问一下:
为什么我们不得不使用“new”来分配一个类,而不是像使用struct那样简单地初始化这些字段?
由于列表中的这三件事,你必须分配一个“新”类。 您需要从长期存储中分配新内存,并且需要将对该存储的引用传递给构造函数。 “新”是知道如何做到这一点的运营商。
您不必在结构上调用“新”,因为不需要分配“最终”存储; 最终的存储已经存在 。 新的价值将会到达某个地方,而且您已经通过其他方式获得了这种存储空间。 值类型不需要新的分配; 他们所需要的只是初始化。 您只需确保存储已正确初始化,并且您通常可以在不调用构造函数的情况下执行此操作。 这样做当然意味着您有可能被观察到由用户代码处于部分初始化状态的值类型变量。
总结:调用ctor对于值类型是可选的,因为在初始化值类型的实例时不需要分配新内存,并且因为跳过构造函数调用意味着您跳过短期分配和副本。 您为提高性能而付出的代价是用户代码可以看到部分初始化的结构。
因为结构是值类型,类是引用类型。 所以结构与int,double等属于同一类。
链接地址: http://www.djcxy.com/p/78883.html上一篇: Why is it possible to instantiate a struct without the new keyword?