【问题标题】:Initialization behavior of class members of primitive type原始类型的类成员的初始化行为
【发布时间】:2020-03-05 05:58:50
【问题描述】:

我知道这里有很多关于此主题的已回答问题,但我找不到完全回答我的问题的问题。

下面我根据我对初始化的理解(从 C++17 开始)做出一些假设。如果有人能指出/纠正我的错误,那就太好了。

给定类型

struct A
{
    int x;  
};

创建局部变量根本不会初始化对象

A a;  // a.x is indeterminate, accessing it is UB

但是,我们可以通过以下方式强制聚合初始化

A a{};
A a = {};

a.x 初始化为0

现在,给定类型

struct B
{
    int x;
    std::string s;
};

创建局部变量默认初始化对象

B b;

这导致b.s被默认初始化(因为它是一个非POD)但b.x是不确定的,访问它仍然是UB。

接下来,我们有

struct C
{
    int x = 0;
    std::string s;
};

创建局部变量默认初始化对象

C c;

这导致 C.s 被默认初始化(因为它是一个非 POD)和 c.x 被复制初始化,行为是明确定义的。

最后,让我们比较一些类型并检查它们是否具有相同的初始化行为。我假设如果我创建一个(默认初始化的)局部变量(A a;),这些类型之间没有区别。

案例A

struct A1
{
    int x;  
};

struct A2
{
    A2() { }
    int x;  
};

struct A3
{
    A3() = default;
    int x;  
};

x 从未初始化,它的值是不确定的。

案例 B

struct B1
{
    int x{};
};

struct B2
{
    B2() : x{} { }
    int x;  
};

struct B3
{
    B3() = default;
    int x = 0;  
};

x 总是被初始化,它的值是0

案例 C

struct C1
{
    int x;
    std::string s;
};

struct C2
{
    C2() { }
    int x;
    std::string s;
};

struct C3
{
    C3() = default;
    int x;
    std::string s;
};

s 总是默认初始化,但x 从不初始化,它的值是不确定的。

这些陈述是否正确,如果不正确,错误在哪里,实际行为是什么?

【问题讨论】:

  • 你的假设是正确的。
  • 经验法则:如果类型有构造函数,则不需要任何工作,构造函数会做。如果没有,则不会为您做任何事情,您要么指定一个值,要么得到一个不确定的值。
  • @NathanOliver-ReinstateMonica “如果该类型有构造函数,则不需要工作” 这不是与案例 C 相矛盾吗?这是否意味着 POD 根本没有构造函数(甚至没有隐式生成的构造函数)?
  • 这与案例 C 不矛盾 是的,但 on 可能会争辩说 C 有一个有缺陷的构造函数,因为它没有做“正确的事情”。 POD 确实有一个不执行任何操作的隐式生成的构造函数。这就是为什么它是一个经验法则,而不是“法律”。 POD 是一个例外,因为它们是一个类,但我们希望将它们视为原语。
  • @Timo:什么是 POD?在您将std::string 放入其中的那一刻,它就不再是 POD。您似乎在谈论聚合。

标签: c++ initialization language-lawyer c++17


【解决方案1】:

您错过了一个微妙之处:对于 A3C3,写作 T3 t{};T3() x 初始化为 0,因为默认构造函数在其第一个声明中默认导致值初始化为零初始化对象and default-initialize it

【讨论】:

  • 是的,我没有故意提到零初始化,因为明确使用了括号或大括号。因为通常不会写std::string s{};std::vector<int> vec{}; 而不是std::string s;std::vector<int> vec;。我专门针对这种语法。
  • @Timo:对于你的第一个 A,你提到了这两个,像 vector::resize 这样的东西做值初始化,所以我认为它是相关的。
猜你喜欢
  • 2015-11-15
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
相关资源
最近更新 更多