值初始化 C++

Posted

技术标签:

【中文标题】值初始化 C++【英文标题】:Value initialization c++ 【发布时间】:2019-01-03 20:40:54 【问题描述】:

在值初始化上阅读 cppreference,我得出了这个结论:

    如果 T 是没有默认构造函数或具有 用户提供或删除的默认构造函数,对象为 默认初始化;

还有例子:

struct T3

    int mem1;
    std::string mem2;
    T3()   // user-provided default constructor
;

阅读文章默认initialization

如果 T 是非 POD(C++11 前)类类型,则构造函数为 考虑并受到针对空的重载决议 参数列表。选择的构造函数(这是默认的构造函数之一 构造函数)被调用为新的提供初始值 对象;

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

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

这适用于示例,T是类类型,这意味着重载决策应该选择候选者来初始化值(用户提供的默认构造函数),但它是空的,所以mem1应该保留不确定的值(这是真的)但同样应该是mem2,但那是“默认初始化”为“”,这是为什么呢?它是否递归工作?类类型的 T 的每个成员都服从第一规则?

我现在很困惑。


2)如果 T 是一个类类型,其默认构造函数既不是 用户提供或删除(也就是说,它可能是一个类 隐式定义或默认的默认构造函数),对象是 零初始化,然后默认初始化,如果它有 非平凡的默认构造函数;

还有例子:

struct T1

    int mem1;
    std::string mem2;
; // implicit default constructor

mem1 被零初始化为 0,但是“非平凡”的默认构造函数是什么意思? mem2 也默认初始化为“”,但是我仍然不确定,“非平凡的默认构造函数”是什么意思?默认构造函数应该由编译器生成,但是它如何决定什么是非平凡的——如果非平凡的默认构造函数意味着它必须初始化对象——与上面相同的问题,是否意味着每个对象都使用默认构造函数初始化?

【问题讨论】:

记住:T3() T3() = default;相同,或者根本不写ctor(is与@987654331 相同@)。 参见en.cppreference.com/w/cpp/language/default_constructor - “平凡的默认构造函数”部分。 【参考方案1】:

应该是mem2,但那是“默认初始化”为“”,这是为什么呢?它是否递归工作?类类型的 T 的每个成员都服从第一规则?

你的怀疑是正确的。当您默认初始化类时,您默认初始化其每个成员,因为在您的构造函数中未指定初始化。由于std::string 有一个用户提供的默认构造函数,它被调用并将字符串对象初始化为空。

但是“非平凡”的默认构造函数是什么意思?

平凡的构造函数是什么都不做的构造函数。对于 T 类型,它的构造函数是微不足道的,如果

构造函数不是用户提供的(即隐式定义或默认) T 没有虚成员函数 T 没有虚拟基类 T 没有带有大括号或等号初始值设定项的非静态成员。 T 的每个直接基数都有一个简单的默认构造函数 类类型的每个非静态成员都有一个普通的默认构造函数

所以在T1 的情况下,您没有平凡的构造函数,因为std::string 的默认构造函数是不平凡的。

【讨论】:

【参考方案2】:

这适用于示例,T 是类类型,这意味着重载决策应该选择候选者来初始化值(用户提供的默认构造函数),但它是空的,所以 mem1 应该保留未确定的值(多数民众赞成在true ) 但同样应该是 mem2,但那是“默认初始化”为“”,这是为什么呢?

如果你从member initializer list 中省略了一个数据成员,那么它会被默认初始化,这对于std::string 意味着调用它的默认构造函数并将其初始化为一个空字符串。您的默认构造函数没有成员初始化列表,因此所有成员都被默认初始化。

“非平凡”的默认构造函数是什么意思?

您可以找到一个简单的构造函数here 的要求。非平凡的默认构造函数只是一个默认构造函数,它不尊重平凡构造函数的所有要求。简而言之,一个微不足道的默认构造函数除了标记对象生命周期的开始之外,根本不做任何事情(甚至在幕后)。

是否意味着每个对象都使用默认构造函数进行初始化?

如前所述,默认构造函数(与任何其他构造函数一样)将默认初始化成员初始化器列表中未指定的任何数据成员。由于默认为空,默认构造函数将递归地导致默认初始化,除非内部成员使用成员初始化器列表指定替代初始化。

【讨论】:

以上是关于值初始化 C++的主要内容,如果未能解决你的问题,请参考以下文章

C++ 是不是对 POD typedef 进行值初始化?

未初始化的 int 值始终相同 (C++)

c++ 用新类初始化二维向量;默认值更改

有没有办法让 C++ 结构值初始化所有 POD 成员变量?

为啥 C++ 不能用“超类”类型的右值初始化“派生类”类型的变量?

在 C++ 中使用 memset 初始化具有不同值的结构数组元素