阅读有关值初始化的cppreference,我来了:
1)如果T是没有默认构造函数或带有 用户提供或删除的默认构造函数,对象为 默认初始化;
示例:
struct T3
{
int mem1;
std::string mem2;
T3() { } // user-provided default constructor
};
阅读有关默认initialization的文章
如果T是非POD(直到C ++ 11)类类型,则构造函数为 考虑并针对超载进行过载解决 参数列表。选择的构造函数(这是默认的构造函数之一 调用)以提供新的初始值 对象;
如果T是数组类型,则数组的每个元素都是 默认初始化;
否则,什么也不做:具有自动存储功能的对象 持续时间(及其子对象)被初始化为不确定 值。
这适用于示例,T是类类型,这意味着重载分辨率应选择候选值来初始化值(用户提供的默认构造函数),但是它为空,因此mem1
应该保留不确定的值(即true),但应为mem2
,但是将其“默认初始化”为“”,这是为什么呢?它可以递归工作吗?每个属于类类型的T都要服从第一条规则?
我现在很困惑。
2)如果T是具有默认构造函数的类类型,则默认构造函数既不是 用户提供或删除的(即,可能是具有 隐式定义或默认的默认构造函数),该对象是 零初始化,如果具有 非平凡的默认构造函数;
示例:
struct T1
{
int mem1;
std::string mem2;
}; // implicit default constructor
mem1
被零初始化为0,但是“非平凡”的默认构造函数是什么意思? mem2
也默认初始化为“”,但是我仍然不确定,“非平凡的默认构造函数”是什么意思?默认构造函数应由编译器生成,但是它如何决定什么是非平凡的—如果非平凡的默认构造函数意味着它必须初始化对象,则与上面相同的问题,是否意味着每个对象都使用默认构造函数初始化吗?
答案 0 :(得分:3)
应该与mem2相同,但是“默认初始化”为“”,这是为什么呢?它可以递归工作吗?每个属于类类型的T都要服从第一条规则?
您的怀疑是正确的。当您默认初始化该类时,由于您的构造函数中未指定任何初始化,因此您将默认初始化其每个成员。由于std::string
有一个用户提供的默认构造函数被调用,它将字符串对象初始化为空。
“非平凡”默认构造函数意味着什么?
琐碎的构造函数是不做任何事情的构造函数。对于类型T
,它的构造函数是否简单
T
没有虚拟成员函数T
没有虚拟基类T
没有带有大括号或相等初始化程序的非静态成员。T
的每个直接基都有一个简单的默认构造函数因此,在T1
的情况下,您没有琐碎的构造函数,因为std::string
的默认构造函数是非琐碎的。
答案 1 :(得分:0)
这适用于示例,T是类类型,这意味着重载分辨率应选择要初始化值的候选对象(用户提供的默认构造函数),但是它为空,因此mem1应该保留不确定值(即true),但应该是mem2,但这是“默认初始化”为“”的,为什么?
如果您从member initializer list中省略了一个数据成员,那么它将被默认初始化,对于std::string
来说,这意味着调用它的默认构造函数并将其初始化为一个空字符串。您的默认构造函数没有成员初始化程序列表,因此所有成员都将默认初始化。
“非平凡”的默认构造函数意味着什么?
您可以找到琐碎的构造函数here的要求。非平凡的默认构造函数只是一个不遵守平凡构造函数的所有要求的默认构造函数。简而言之,一个简单的默认构造函数除了标记对象生命周期的开始之外,什么也不做(即使在幕后)。
这是否意味着每个对象都使用默认构造函数初始化了?
如前所述,默认构造函数(与其他任何构造函数一样)将默认初始化成员初始化列表中未指定的任何数据成员。由于默认情况下为空,因此默认构造函数将递归导致默认初始化,除非内部成员使用成员初始化程序列表指定替代初始化。