C#中的结构体要使用new来实例化吗?还是直接声明后直接使用?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中的结构体要使用new来实例化吗?还是直接声明后直接使用?相关的知识,希望对你有一定的参考价值。

有何区别?

结构无需进行new,就可以直接使用
比如:
MyStruct struct;
struct.Method();
对于类的话,这是错误的

原因如下:
结构为值类型,而new用于为引用类型(类、对象、接口等)分配引用(内存地址),值类型存储于堆中,无需使用new。
比如:
int x;和MyStruct struct;
是一样的道理
这的x、struct都是值类型的

最后结构可以用new 也可以不用new
上面那位是胡说
参考技术A 声明结构的默认(无参数)构造函数是错误的。总是提供默认构造函数以将结构成员初始化为它们的默认值。在结构中初始化实例字段也是错误的。

如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当的构造函数。与类不同,结构的实例化可以不使用 new 运算符。如果不使用 new,则在初始化所有字段之前,字段都保持未赋值状态且对象不可用。本回答被提问者采纳
参考技术B struct属于值类型,可以不用new,如果不new,结构体内的值就都是未赋值状态,需要在使用之前赋值,不然编译器会报错。若new了,结构体会调用无参构造函数,会初始化内部的值,比如int就会初始化为0,现在使用编译器就不会报错了。楼上所谓的“不能new”是完全错误的,写两行代码试试不就知道了? 参考技术C 结构体不是存在堆中的,所以不用new ,也不能new
结构体是值类型的。不是引用类型的。你要new 就报错

在声明“std::vector<X> f();”中,“std::vector<X>”是一个实例化吗?

【中文标题】在声明“std::vector<X> f();”中,“std::vector<X>”是一个实例化吗?【英文标题】:In the declaration "std::vector<X> f();", is "std::vector<X>" an instantiation? 【发布时间】:2011-10-11 18:42:26 【问题描述】:

C++ 语言标准规定了标准库中有关模板组件的以下内容:

效果未定义...如果在实例化模板组件时将不完整的类型用作模板参数,除非该组件特别允许 (C++11 §17.6.4.8/2)。

以下是否会导致 std::vector 类模板的实例化?

class X;
std::vector<X> f(); // Declaration only; we will define it when X is complete

换个说法,在函数声明std::vector&lt;X&gt; f();中,std::vector是用参数X实例化的吗?或者,直到 f() 被 odr 使用或定义后,std::vector&lt;X&gt; 才被实例化?

同样,以下是否会导致 std::vector 类模板的实例化?

class X;
typedef std::vector<X> XVector; // We will complete X before we use XVector

虽然我在这些示例中使用 std::vector,但该问题同样适用于所有模板。

【问题讨论】:

一个好的答案将提供对 C++ 语言标准的参考。我搜索了语言标准,但找不到明确的答案。 我以前从未见过在部分编译过程中使用“未定义”... 你为什么想知道? 当你评论here时,你为什么确信它确实是在实例化模板组件,有什么想法吗? @jeffamaphone:我想知道,因为我很好奇。此外,因为它具有广泛的实际意义,正如辩论 in the answers and comments to this question 所证明的那样。 【参考方案1】:

§ 14.7.1\1 隐式实例化 [temp.inst]

除非类模板特化已明确 实例化 (14.7.2) 或显式特化 (14.7.3) 类 模板特化是隐式实例化的,当 专业化是在需要的上下文中引用的 完全定义对象类型或当类的完整性 type 影响程序的语义。 隐式实例化 类模板特化导致隐式实例化 声明,但不是定义或默认参数, 类成员函数、成员类、静态数据成员和 会员模板;它会导致隐式实例化 成员匿名工会的定义。除非是班级成员 模板或成员模板已被显式实例化或 显式特化,成员的特化是隐式的 当特化在上下文中被引用时被实例化 要求成员定义存在; 特别是, 静态数据的初始化(以及任何相关的副作用) 除非静态数据成员本身被用于 一种需要静态数据成员的定义存在的方式。

§ 8.3.5\9 函数 [dcl.fct]

类型不应在返回或参数类型中定义。的类型 函数定义的参数或返回类型不应是 不完整的类类型(可能是 cv 限定的),除非函数 定义嵌套在该类的成员规范中 (包括在类中定义的嵌套类中的定义)。

§ 3.1\2 声明和定义 [basic.def]

声明是一个定义,除非它声明一个函数 指定函数的主体 (8.4), 它包含 extern 说明符 (7.1.1)或链接规范25(7.5),既不是初始化器 也不是函数体,它在类中声明了一个静态数据成员 定义(9.4),它是一个类名声明(9.1),它是一个 opaque-enum-declaration (7.2),或者是 typedef 声明 (7.1.3), 使用声明(7.3.3),静态断言声明(第 7 条), 一个属性声明(第 7 条),一个空声明(第 7 条), 或使用指令 (7.3.4)。

只有在必需时才会被实例化。我在任何地方都找不到明确的定义,但第二句话说那些声明不是定义,这对我来说似乎是一样的。

【讨论】:

有趣。但是,这个答案似乎没有定论……我认为第一句话尤其成问题。一方面,该类型用于允许不完整类型的上下文中。另一方面,似乎“类类型的完整性会影响程序的语义”,不是吗? 虽然真的,影响程序语义的并不是类类型的完整性本身; 用于实例化类模板的类型的完整性会影响程序的语义。嗯嗯嗯嗯嗯…… 我认为从程序的语义来看,它基本上是指引用对象的一个​​成员。 [EDIT no wait, that's syntax] 因为我们不这样做,而且对象的大小并不重要,所以允许使用不完整的类型。【参考方案2】:

不,它不会实例化模板。 Mooing Duck 的回答提供了所有必要的引用,但这里有一些分析。

如果不存在需要完全定义的类型(第 14.7.1/1 节),则默认情况下不会发生实例化。函数定义特别需要完整类型(第 8.3.5/9 节),但问题是标准的其他部分是否也要求其他声明。

但是定义有一个特殊的例外,它表明非定义声明确实不同:

函数定义的参数类型或返回类型不应是不完整的类类型(可能是 cv 限定的),除非函数定义嵌套在该类的成员规范中(包括定义的嵌套类中的定义)在课堂上)。

成员规范中的函数定义有什么特别之处?因为一个成员规范不能两次声明同一个函数(§9.2/1),并且成员函数体在所有成员声明之后处理(§3.3.7/1.1)。本质上,嵌套成员函数定义在第一次传递期间被视为声明,然后在处理完整个成员规范并且类完成后定义(第 9.2/2 节)。 §8.3.5/9 规定第一次通过时允许不完整的类,但第二次则不允许。

对函数声明和实例化的标准规则进行详尽、明确的搜索是相当繁重的。但是这个例子虽然仅限于成员函数和封闭类型的完整性,但可以合理地扩展到其他函数和类型。无论如何,这是区分的很好的证据。

【讨论】:

以上是关于C#中的结构体要使用new来实例化吗?还是直接声明后直接使用?的主要内容,如果未能解决你的问题,请参考以下文章

我们可以声明一个抽象方法来返回抽象超类中的子类对象而不需要新的实例化吗?

C#为啥接口可以实例化一个实现该接口的类?

在c++中,接口能实例化吗?下面是接口实例化吗?operFactory是啥?我初学。

java 泛型对象能实例化吗T t=new T()

接口可以实例化吗

swift 中使用Codable进行数据解析