使用非平凡的构造函数初始化联合

2021-12-30 00:00:00 constructor c++ multiplatform

我有一个结构,我创建了一个自定义构造函数来将成员初始化为 0.我在较旧的编译器中看到,在发布模式下,如果没有将 memset 设置为 0,则不会初始化这些值.

I have a structure which I create a custom constructor to initialize the members to 0's. I've seen in older compilers that when in release mode, without doing a memset to 0, the values are not initialized.

我现在想在联合中使用这个结构,但是因为它有一个非平凡的构造函数而出错.

I now want to use this structure in a union, but get errors because it has a non-trivial constructor.

那么,问题 1. 默认编译器实现的构造函数是否保证结构的所有成员都将被初始化为空?非平凡的构造函数只是将所有成员的 memset 设置为0"以确保结构清晰.

So, question 1. Does the default compiler implemented constructor guarantee that all members of a structure will be null initialized? The non-trivial constructor just does a memset of all the members to '0' to ensure a clean structure.

问题 2:如果必须在基本结构上指定构造函数,如何实现联合以包含该元素并确保初始化为 0 的基本元素?

Question 2: If a constructor must be specified on the base structure, how can a union be implemented to contain that element and ensure a 0 initialized base element?

推荐答案

问题 1:根据 C++ 标准,默认构造函数确实将 POD 成员初始化为 0.请参阅下面引用的文本.

Question 1: Default constructors do initialize POD members to 0 according to the C++ standard. See the quoted text below.

问题 2:如果必须在基类中指定构造函数,则该类不能成为联合的一部分.

Question 2: If a constructor must be specified in a base class, then that class cannot be part of a union.

最后,你可以为你的联合提供一个构造函数:

Finally, you can provide a constructor for your union:

union U 
{
   A a;
   B b;

   U() { memset( this, 0, sizeof( U ) ); }
};

对于第一季度:

来自 C++03,12.1 构造函数,第 190 页

From C++03, 12.1 Constructors, pg 190

隐式定义的默认构造函数执行一组初始化将由用户为该类编写的默认构造函数执行的类,具有空的 mem-initializer-list (12.6.2) 和空的函数体.

The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with an empty mem-initializer-list (12.6.2) and an empty function body.

来自 C++03,8.5 初始化器,第 145 页

From C++03, 8.5 Initializers, pg 145

默认初始化一个 T 类型的对象意味着:

To default-initialize an object of type T means:

  • 如果 T 是非 POD 类类型(第 9 条),默认构造函数因为 T 被称为(并且如果 T 初始化是病态的没有可访问的默认值构造函数);
  • 如果 T 是数组类型,则每个元素都默认初始化;
  • 否则,对象将被零初始化.

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

To zero-initialize an object of type T means:

  • 如果 T 是标量类型 (3.9),则对象设置为 0(零)转换为 T 的值;
  • 如果 T 是非联合类类型,则每个非静态数据成员和每个基类子对象都被零初始化;
  • 如果 T 是联合类型,则对象的第一个命名数据成员被零初始化;
  • 如果 T 是数组类型,则每个元素都初始化为零;
  • 如果 T 是引用类型,则不执行初始化.

对于第二季度:

来自 C++03,12.1 构造函数,第 190 页

From C++03, 12.1 Constructors, pg 190

如果构造函数是隐式声明的默认构造函数并且如果:

A constructor is trivial if it is an implicitly-declared default constructor and if:

  • 它的类没有虚函数(10.3)和虚基类(10.1),并且
  • 其类的所有直接基类都有简单的构造函数,并且
  • 对于其类的所有非静态数据成员,属于类类型(或数组其中),每个这样的类都有一个简单的构造函数

来自 C++03,9.5 联合,第 162 页

From C++03, 9.5 Unions, pg 162

联合可以有成员函数(包括构造函数和析构函数),但不能有虚拟(10.3)函数.联合不应有基类.联合不应用作基类.具有非平凡构造函数 (12.1)、非平凡复制构造函数 (12.8)、非平凡析构函数 (12.4) 或非平凡的类的对象复制赋值运算符 (13.5.3, 12.8) 不能是联合的成员,也不能是此类对象的数组

A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. A union shall not have base classes. A union shall not be used as a base class.An object of a class with a non-trivial constructor (12.1), a non-trivial copy constructor (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment operator (13.5.3, 12.8) cannot be a member of a union, nor can an array of such objects

相关文章