当前位置: 首页 > 知识库问答 >
问题:

在不使用默认构造函数的情况下声明POD结构时实例化什么?

凤棋
2023-03-14

当我们的团队处理关于C代码中POD的单元化成员的valgrind警告时,我想到了这个有趣的答案:

https://stackoverflow.com/a/5914697/629530

重申要点,考虑C中的以下POD结构:

struct C
{
    int x; 
    int y;
};

构造C类型对象的以下调用调用默认构造函数,成员使用该默认构造函数初始化(再次复制Martin York答案中的代码和注释):

C  c = C();      // Zero initialize using default constructor
C  c{};          // Latest versions accept this syntax.
C* c = new C();  // Zero initialize a dynamically allocated object.

有道理。Martin York继续指出,使用以下声明,c的成员不是通过构造函数初始化的,因此包含未定义的数据:

C  c;            // members are random
C* c = new C;    // members are random (more officially undefined).

这很有趣。我以前使用过POD类型的括号-init-list初始化,但我没有意识到C c;不会调用POD类型的默认构造函数。他的回答满足了这个问题,但我想知道当声明后者时,具体实例化了什么,非默认构造的c对象。具体来说,以下内容对我很有帮助:

  1. POD类型的非默认初始化的官方名称是什么?我在谷歌上搜索这个机制时遇到了麻烦,因为我不知道它的名字

更新。

谢谢你的意见。这已经复制到一个问题,只有一个答案:https://stackoverflow.com/a/8860787/629530

根据该答案(以及与之重复的问题的答案),没有括号的形式声明称为“默认初始化”:

Info *p = new Info;      <------- Default Initialization

对于默认初始化,提出了以下关于初始化的要点:

默认初始化T类型的对象意味着:

  • 如果T是非POD类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是病态的)
  • 如果T是数组类型,则每个元素默认初始化
  • 否则,对象初始化为零

我可能误解了什么,但上面提出的名为C的结构是不是数组的POD类型。因此它应该是零初始化的?但是,成员不是零初始化的,而是包含未定义的值。我如何协调这一点?

共有1个答案

冯胤
2023-03-14

默认初始化T类型的对象意味着:

... 否则,对象初始化为零。

不。

您的第一个链接答案是正确的,大约从C11开始,这称为默认初始化。这与默认构造或值初始化不同。

第二个链接的答案可能对C 03是正确的,但对C 11以后是错误的(尽管它是在2012年编写的)。我没有03标准的副本要验证,而且那是很久以前的事了。

默认初始化的影响包括:

>

如果T是数组类型,则数组的每个元素都默认初始化;

否则,什么也不做:具有自动存储持续时间的对象(及其子对象)被初始化为不确定值。

N4659的本地副本同意上述摘要:

11.6初始值设定项[dcl.init]

...

(7.3)否则,不执行初始化

关于新表达式的部分甚至提到了11.6,然后说

注意:如果未执行初始化,则对象具有不确定值。-结束注释

目前的草案

9.3初始化器[dcl.init]

...

(7.3)否则,不执行初始化。

 类似资料:
  • 我有一个类,它有一个默认构造函数,还有一个重载构造函数,它接受一组参数。这些参数与对象上的字段匹配,并在构造时指定。此时,我需要用于其他目的的默认构造函数,因此如果可以的话,我希望保留它。 我的问题:如果我删除默认的构造函数并传递JSON字符串,对象反序列化正确,并传递构造函数参数没有任何问题。我最终以我所期望的方式找回填充的对象。但是,一旦我将默认构造函数添加到对象中,当我调用

  • 我是Spring的新手。我创建了一个bean类和一个配置文件,如下所示: Beans.xml Employee.java 当我尝试使用Application Context获取bean时,它会给出以下异常: 线程“main”组织中出现异常。springframework。豆。工厂BeanCreationException:创建在类路径资源[Problem.xml]中定义的名为“employee”的

  • 我想知道为什么Spring boot可以反序列化没有默认构造函数的类由Jackson的ObjectMapper,但是当我在单元测试中手动使用ObjectMapper时,它不能反序列化(com.fasterxml.jackson.databind.exc.Invalid定义异常:不能构造实例的(没有创建者,像默认构造函数,存在):不能反序列化从对象值(没有基于委托或属性的创建者))。 这是我的控制器

  • 问题内容: 我想使用com.fasterxml.jackson.databind.ObjectMapper序列化和反序列化不可变对象。 不可变类如下所示(只有3个内部属性,获取器和构造函数): 但是,当我运行此单元测试时: 我得到这个例外: 这个异常要求我创建一个默认的构造函数,但这是一个不可变的对象,所以我不想拥有它。它将如何设置内部属性?这会完全混淆API的用户。 所以我的问题是: 我可以在没

  • 问题内容: 默认构造函数到底是什么?你能告诉我以下哪个是默认构造函数,它与其他构造函数有何不同? 问题答案: 他们都不是。如果定义,则不是默认值。 除非你定义另一个构造函数,否则默认构造函数是自动生成的无参数构造函数。任何未初始化的字段都将设置为其默认值。对于你的榜样,它看起来像这样假设的类型String,int以及int,那类本身是公共的: 这与 完全没有构造函数。但是,如果定义至少一个构造函数

  • 我有一个有两个构造函数的类。 有一个具有两个构造函数的类Sample。需要在Sample类中实例化另外三个类(ClassOne,ClassTwo和ClassIII)。所有三个类都包含默认和参数化构造函数。如果调用了Sample类的默认构造函数,则应调用ClassOne,ClassTwo和ClassIII的默认辅助构造函数。如果调用Samples参数化构造函数,则调用ClassOne、ClassII