使用非平凡构造函数初始化联合 [英] Initializing a union with a non-trivial constructor

查看:188
本文介绍了使用非平凡构造函数初始化联合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构,我创建一个自定义构造函数将成员初始化为0。我在旧编译器中看到,在释放模式下,没有做一个memset到0,这些值不会被初始化。



我现在想在这个结构中使用联合,但得到错误,因为它有一个非平凡的构造函数。



所以,问题1.默认编译器实现的构造函数保证结构的所有成员将为null初始化?非平凡构造函数只是将所有成员的memset设置为'0',以确保一个干净的结构。



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

解决方案

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



问题2:如果必须在基类中指定构造函数,那么该类不能是联合的一部分。



最后,您可以为您的联盟提供构造函数:

  union U 
{
A a;
B b;

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

对于Q1:



+03,12.1构造函数,第190页



隐式定义的默认构造函数执行
类的初始化集合,将由用户编写



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



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




  • 如果T是非POD类类型
    (第9节),调用T的默认构造函数
    (如果T
    没有可访问的缺省值,则
    初始化不成形b $ b constructor);

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


要初始化类型T的对象意味着:




  • 如果T是标量类型(3.9),则将对象设置为值的0(零)转换为T;

  • 如果T是非联合类类型,每个非静态数据成员和每个基类子对象都是零初始化的

  • 如果T是联合类型,则对象的第一个命名数据成员是零初始化的; b
  • 如果T是数组类型,则每个元素都被初始化;

  • 如果T是引用类型,则不执行初始化。



/ p>

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



构造函数如果是隐式 - 声明的默认构造函数和if:




  • 它的类没有虚函数(10.3)和虚拟基类(10.1) >
  • 其类的所有直接基类都具有简单的构造函数,并且

  • 用于类的所有非静态数据成员b $ b),每个类都有一个琐碎的构造函数



从C ++ 03,9.5联合,第162页



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


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.

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.

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?

解决方案

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

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 ) ); }
};

For Q1:

From C++03, 12.1 Constructors, pg 190

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.

From C++03, 8.5 Initializers, pg 145

To default-initialize an object of type T means:

  • if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is an array type, each element is default-initialized;
  • otherwise, the object is zero-initialized.

To zero-initialize an object of type T means:

  • if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
  • if T is a non-union class type, each non static data member and each base-class subobject is zero-initialized;
  • if T is a union type, the object’s first named data member is zero-initialized;
  • if T is an array type, each element is zero-initialized;
  • if T is a reference type, no initialization is performed.

For Q2:

From C++03, 12.1 Constructors, pg 190

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

  • its class has no virtual functions (10.3) and no virtual base classes (10.1), and
  • all the direct base classes of its class have trivial constructors, and
  • for all the nonstatic data members of its class that are of class type (or array thereof), each such class has a trivial constructor

From C++03, 9.5 Unions, pg 162

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

这篇关于使用非平凡构造函数初始化联合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆