【问题标题】:Zero initialization of string and string array (C++)字符串和字符串数组的零初始化(C++)
【发布时间】:2019-12-08 12:24:51
【问题描述】:

根据https://en.cppreference.com/w/cpp/language/zero_initialization

在文档提供的示例中:

std::string s; // is first zero-initialized to indeterminate value
               // then default-initialized to ""

如果语法针对static T object;,为什么string s; 会发生零初始化?

为什么在默认初始化之前发生零初始化,为什么两者都允许发生?

零初始化的效果是:

  • 如果 T 是标量类型,则对象的初始值为整数 常量零显式转换为 T。
  • 如果 T 是非联合类 类型,所有基类和非静态数据成员都是 零初始化,并且所有填充都初始化为零位。这 构造函数(如果有)将被忽略。
  • 如果 T 是联合类型,则第一个 非静态命名数据成员是零初始化的,所有填充都是 初始化为零位。
  • 如果 T 是数组类型,则每个元素都是 零初始化
  • 如果 T 是引用类型,则什么都不做。

如果我初始化string array[2] = {"Test1"}; 会怎样?我知道该数组将包含“Test1”和空字符串“”。

但是根据上面的文档,

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

数据类型是对象/引用类型的字符串?

如果 T 是引用类型,则什么都不做。

什么都没做?我想也许会调用一个构造函数。肯定是空字符串吗?

【问题讨论】:

标签: c++ arrays initialization


【解决方案1】:

(除非另有说明,否则此答案中的所有声明都假定在命名空间范围内。)

如果语法是 for,为什么 string s; 会发生零初始化 static T object;?
为什么之前会发生零初始化 默认初始化,为什么两者都允许发生?

具有静态存储持续时间的变量首先在编译时初始化为零,然后在运行时可选地动态初始化。 static T object; 声明了一个静态存储持续时间的对象。对于像

这样的简单声明
int x;

不执行动态初始化。对于更复杂的声明,例如

std::string s;

对字符串进行零初始化可能会导致类不变量损坏的无效字符串。因此,动态初始化调用默认构造函数来保证对象是有效的。

如果我初始化string array[2] = {"Test1"}; 会怎样?我知道 数组将包含“Test1”和空字符串“”。

首先,在编译时,这两个对象都是零初始化的,导致可能的无效状态。然后,在运行时调用构造函数(const char* 第一个对象的构造函数和第二个对象的默认构造函数),并构造有效的对象。

数据类型是string是对象/引用类型?

std::string 是对象类型而不是引用类型。

[对于引用类型] 什么都没做?我想也许是一个构造函数 会被调用。肯定是空字符串吗?

引用类型不被视为实际的“对象”,因此没有必要指定其零初始化语义。

【讨论】:

    【解决方案2】:

    如果语法针对static T object;,为什么string s; 会发生零初始化?

    为什么在默认初始化之前发生零初始化,为什么两者都允许发生?

    在您链接到的页面中,它定义了一个非局部变量。

    非局部变量的初始化分两个阶段。

    1. 静态初始化。
    2. 动态初始化(如果适用)。

    静态初始化阶段,使用常量初始化零初始化

    对变量进行初始化

    动态初始化会被使用(如果适用),例如用于具有适当构造函数的对象或使用可在运行时计算的表达式初始化的对象。

    您可以在https://en.cppreference.com 阅读有关该主题的更多信息。

    什么都没做?我想也许会调用一个构造函数。肯定是空字符串吗?

    引用不能被零初始化。它只能使用它作为引用的对象来初始化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-02
      • 2014-10-16
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      相关资源
      最近更新 更多