热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

零初始化初始化列表中的数组成员-Zero-Initializearraymemberininitializationlist

IhaveaclasswithanarraymemberthatIwouldliketoinitializetoallzeros.我有一个数组成员的类,我想初始化为全

I have a class with an array member that I would like to initialize to all zeros.

我有一个数组成员的类,我想初始化为全零。

class X
{
private:
    int m_array[10];
};

For a local variable, there is a straightforward way to zero-initialize (see here):

对于局部变量,有一种简单的零初始化方法(参见此处):

int myArray[10] = {};

Also, the class member m_array clearly needs to be initialized, as default-initializing ints will just leave random garbage, as explained here.

此外,类成员m_array显然需要初始化,因为默认初始化的int将只留下随机垃圾,如此处所述。

However, I can see two ways of doing this for a member array:

但是,我可以看到两种方法为成员数组执行此操作:

With parentheses:

public:
    X()
    : m_array()
    {}

With braces:

public:
    X()
    : m_array{}
    {}

Are both correct? Is there any difference between the two in C++11?

两个都正确吗?这两者在C ++ 11中有什么区别吗?

3 个解决方案

#1


12  

Initialising any member with () performs value initialisation.

使用()初始化任何成员执行值初始化。

Initialising any class type with a default constructor with {} performs value initialisation.

使用带有{}的默认构造函数初始化任何类类型都会执行值初始化。

Initialising any other aggregate type (including arrays) with {} performs list initialisation, and is equivalent to initialising each of the aggregate's members with {}.

使用{}初始化任何其他聚合类型(包括数组)执行列表初始化,相当于使用{}初始化每个聚合的成员。

Initialising any reference type with {} constructs a temporary object, which is initialised from {}, and binds the reference to that temporary.

使用{}初始化任何引用类型构造一个临时对象,该对象从{}初始化,并将引用绑定到该临时对象。

Initialising any other type with {} performs value initialisation.

使用{}初始化任何其他类型执行值初始化。

Therefore, for pretty much all types, initialisation from {} will give the same result as value initialisation. You cannot have arrays of references, so those cannot be an exception. You might be able to construct arrays of aggregate class types without a default constructor, but compilers are not in agreement on the exact rules. But to get back to your question, all these corner cases do not really matter for you: for your specific array element type, they have the exact same effect.

因此,对于几乎所有类型,从{}初始化将产生与值初始化相同的结果。您不能拥有引用数组,因此这些不能成为例外。您可以在没有默认构造函数的情况下构造聚合类类型的数组,但编译器对确切的规则不一致。但是回到你的问题,所有这些极端情况对你来说并不重要:对于你特定的数组元素类型,它们具有完全相同的效果。

#2


11  

The types of initialization can be kind of tedious to go through, but in this case it is trivial. For:

初始化的类型可能有点繁琐,但在这种情况下,它是微不足道的。对于:

public:
    X()
    : m_array()
    {}

since the expression-list between the parentheses are empty, value-initialization occurs. Similarly for:

由于括号之间的表达式列表为空,因此会进行值初始化。同样适用于:

public:
    X()
    : m_array{}
    {}

list-initialization occurs, and subsequently value-initialization since the brace-init-list is empty.

由于brace-init-list为空,因此会发生list-initialization,然后进行值初始化。


To give a more comprehensive answer, let's go through §8.5 of N4140.

为了给出更全面的答案,让我们来看看N4140的§8.5。

  1. If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.17).
  2. 如果没有为对象指定初始化程序,则默认初始化该对象。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定的值,并且如果没有对该对象执行初始化,则该对象保留不确定的值,直到该值被替换(5.17)。

This indeterminate value is what you refer to as garbage values.

这个不确定的值就是你所说的垃圾值。

  1. To zero-initialize an object or reference of type T means:

    零初始化T类型的对象或引用意味着:

    — if T is an array type, each element is zero-initialized

    - 如果T是数组类型,则每个元素都是零初始化的

  2. To value-initialize an object of type T means:

    对T类型的对象进行值初始化意味着:

    — if T is a (possibly cv-qualified) class type ... then the object is default-initialized; ...

    - 如果T是(可能是cv限定的)类类型...那么该对象是默认初始化的; ...

    — if T is an array type, then each element is value-initialized;

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

    — otherwise, the object is zero-initialized.

    - 否则,对象被零初始化。

  3. The semantics of initializers are as follows. ... — If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized (8.5.4).

    初始化器的语义如下。 ... - 如果初始化程序是(非括号的)braced-init-list,则对象或引用是列表初始化的(8.5.4)。

    — If the initializer is (), the object is value-initialized.

    - 如果初始值设定项为(),则对象进行值初始化。

So far it's clear that value initialization will make each element of the array zero since int is not a class type. But we have not yet covered list initialization and aggregate initialization, since an array is an aggregate.

到目前为止,很明显值初始化将使数组的每个元素为零,因为int不是类类型。但是我们还没有介绍列表初始化和聚合初始化,因为数组是一个聚合。

§8.5.4:

  1. List-initialization of an object or reference of type T is defined as follows:

    列表初始化对象或类型T的引用定义如下:

    — If T is an aggregate, aggregate initialization is performed (8.5.1).

    - 如果T是聚合,则执行聚合初始化(8.5.1)。

And back to §8.5.1:

并回到§8.5.1:

  1. If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal-initializer, from an empty initializer list (8.5.4).
  2. 如果列表中的initializer-clause少于聚合中的成员,那么未明确初始化的每个成员都应从其brace-or-equal-initializer初始化,或者如果没有bra-or-equal-initializer,从一个空的初始化列表(8.5.4)。

And we end with §8.5.4 again:

我们再次以§8.5.4结尾:

  1. List-initialization of an object or reference of type T is defined as follows:

    列表初始化对象或类型T的引用定义如下:

    — Otherwise, if the initializer list has no elements, the object is value-initialized.

    - 否则,如果初始化列表没有元素,则对象进行值初始化。

Since traversing the (draft) standard can take breath out of you, I recommend cppreference as it breaks it down pretty good.

由于遍历(草案)标准可能会让你失望,我建议使用cppreference,因为它可以很好地分解它。

Relevant links:

cppreference:

  • aggregate initialization

  • value initialization

Draft standard:

  • N4140

#3


-2  

Parentheses work in C++98, and are calling for zero initialization, which is what you want. I verified on gcc 4.3. Edit: removed incorrect statement about C++11. I also confirmed that empty braces perform empty-list-initialization using clang 3.4 with -std=c++11.

括号在C ++ 98中工作,并且正在调用零初始化,这正是您想要的。我在gcc 4.3上验证过。编辑:删除了关于C ++ 11的错误陈述。我还确认空括号使用clang 3.4和-std = c ++ 11执行空列表初始化。


推荐阅读
  • Introduction(简介)Forbeingapowerfulobject-orientedprogramminglanguage,Cisuseda ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • 工作经验谈之-让百度地图API调用数据库内容 及详解
    这段时间,所在项目中要用到的一个模块,就是让数据库中的内容在百度地图上展现出来,如经纬度。主要实现以下几点功能:1.读取数据库中的经纬度值在百度上标注出来。2.点击标注弹出对应信息。3 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了如何在方法参数中指定一个对象的协议,以及如何调用符合该协议的方法。以一个具体的示例说明了如何在方法参数中指定一个UIView子类对象,并且该对象需要符合PixelUI协议,同时方法需要能够访问该对象的属性。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
author-avatar
树缝中间_324
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有