我有一个结构,我创建一个自定义构造函数来将成员初始化为0.我在较旧的编译器中看到,当处于释放模式时,如果没有将memset设置为0,则不会初始化值.
我现在想在union中使用这个结构,但是因为它有一个非平凡的构造函数而得到错误.
那么,问题1.默认编译器实现的构造函数是否保证结构的所有成员都将为null初始化?非平凡的构造函数只是将所有成员的memset设置为'0'以确保结构清晰.
问题2:如果必须在基础结构上指定构造函数,如何实现联合以包含该元素并确保0初始化的基本元素?
问题1:默认构造函数根据C++标准将POD成员初始化为0.请参阅下面引用的文字.
问题2:如果必须在基类中指定构造函数,则该类不能是联合的一部分.
最后,您可以为您的联合提供构造函数:
union U { A a; B b; U() { memset( this, 0, sizeof( U ) ); } };
对于Q1:
从C++ 03,12.1构造函数,第190页
隐式定义的默认构造函数执行该类的初始化集合,该初始化集合将由用户编写的具有空mem-initializer-list(12.6.2)和空函数体的类的默认构造函数执行.
从C++ 03,8.5 Initializers,第145页
默认初始化T类型的对象意味着:
如果T是非POD类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);
如果T是数组类型,则每个元素都是默认初始化的;
否则,该对象被零初始化.
零初始化T类型的对象意味着:
如果T是标量类型(3.9),则将对象设置为0(零)转换为T的值;
如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的 ;
如果T是联合类型,则对象的第一个命名数据成员为零初始化;
如果T是数组类型,则每个元素都是零初始化的;
如果T是引用类型,则不执行初始化.
第二季度:
从C++ 03,12.1构造函数,第190页
如果构造函数是隐式声明的默认构造函数,并且如果:
它的类没有虚函数(10.3),也没有虚基类(10.1),和
它的所有直接基类都有琐碎的构造函数
对于类类的所有非静态数据成员(或其数组),每个这样的类都有一个简单的构造函数
从C++ 03,9.5 Unions,第162页
联合可以具有成员函数(包括构造函数和析构函数),但不具有虚函数(10.3).工会不得有基类.联合不应该用作基类.具有非平凡构造函数(12.1)的类的对象,非平凡的复制构造函数(12.8),非平凡的析构函数(12.4)或非平凡的复制赋值运算符(13.5.3,12.8)不能是联合的成员,也不能是这类对象的数组
在C++ 11中,事情变得更好了.
你现在可以合法地做到这一点,正如Stroustrup自己所描述的那样(我从维基百科关于C++ 11的文章中得到了这个链接).
维基百科上的示例如下:
#include// Required for placement 'new'. struct Point { Point() {} Point(int x, int y): x_(x), y_(y) {} int x_, y_; }; union U { int z; double w; Point p; // Illegal in C++03; legal in C++11. U() {new(&p) Point();} // Due to the Point member, a constructor // definition is now *required*. };
Stroustrup更详细一些.