为什么C语言中union成员初始化及构造函数使用报错?

为什么定义num时初始化或者用初始化函数Stu_t都会导致报错?
是不是意味着 union 内所有的成员以及嵌套的所有成员都不能在定义时初始化和使用构造函数呢?
如果不让初始化则会不会导致内存里是随机数据呢?

typedef struct Stu_t {
    int num;   // 或者 int num = 0;
    Stu_t () {
        Num = 0;
    }
} Stu;


typedef struct message_t {
    union result_t {
        int aaa;
        Stu stu;
    } result;
} message;


int main() {
    message msg;
    return 0;
}

对 union 内成员逐层嵌套的成员进行定义时初始化和使用构造函数验证,发现都会报错。

阅读 1.7k
3 个回答

为联合类型 union message_t::result_t 添加默认构造函数:

typedef struct message_t
{
    union result_t
    {
        int aaa;
        Stu stu;
        result_t() {}
    } result;
} message;

union 也是一种类。它也需要构造函数。

union 的构造函数通常都是自动生成的。但是有时这个构造函数无法自动生成,就必须要自己写一个。比如,当 union 的一个成员有一个自定义的构造函数,或者含有成员初始化的时候。这个时候,就必须自己显示的给 union 定义一个构造函数。


default-ctor

2
A defaulted default constructor for class X is defined as deleted if:
(2.1)
X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer,

"Trivial"这个词在英语中意味着“不重要的”、“简单的”或“显而易见的”。在计算机科学和编程语言的上下文中,"trivial"通常用来描述那些不需要复杂操作或不需要任何操作就能完成的任务或函数。

在C++中,当我们说一个函数是"trivial"的,我们是在说这个函数不需要任何特别的逻辑或操作来执行其任务。具体来说:

构造函数:如果一个类的构造函数是trivial的,这意味着它不需要执行任何初始化操作,或者它所做的只是简单地复制或移动成员的值。对于POD(Plain Old Data,普通旧数据)类型,构造函数通常是trivial的,因为它们只是数据的简单容器,不需要任何特殊的初始化。

析构函数:如果一个析构函数是trivial的,这意味着对象的销毁不需要任何特别的清理操作。这通常适用于没有动态分配内存或其他资源需要释放的类。

复制和移动操作:如果复制构造函数、复制赋值运算符、移动构造函数和移动赋值运算符是trivial的,这意味着它们不需要执行任何复杂的复制或移动逻辑,只是简单地复制或移动成员的值。

在这个上下文中,"trivial"意味着这些操作是如此简单,以至于编译器可以自动生成它们,而不需要程序员显式定义。这些操作是“平凡的”,因为它们不涉及任何复杂的逻辑,它们的行为是可预测的,不需要程序员的额外干预。

在您提到的联合体(union)的上下文中,如果一个联合体的默认构造函数是trivial的,这意味着创建联合体的实例不需要任何特别的操作,因为它的成员(在这个情况下是变体成员)的默认构造函数也是trivial的,即它们不需要任何初始化操作。如果变体成员有一个非trivial的默认构造函数,那么联合体的默认构造函数就不能是trivial的,因为它需要执行一些操作来初始化那个成员。

为什么叫 trivial? 在这个上下文中如何理解平凡?
在C++编程语言中,"trivial"这个术语用来描述一个特殊的构造函数、析构函数或复制/移动操作的行为。如果一个函数是trivial的,那么它不执行任何操作,或者只执行简单的位复制(bitwise copy)或位移动(bitwise move)。具体来说,一个构造函数是trivial的,如果它满足以下条件之一:

该类没有任何非静态数据成员。
该类的所有非静态数据成员都有trivial的构造函数。
该类的所有非静态数据成员都是通过默认成员初始化器(default member initializer)初始化的。
在您提供的上下文中,提到了一个类X的默认构造函数被定义为已删除(deleted),其中一个条件是X是一个联合体(union),并且有一个变体成员(variant member)具有非平凡的(non-trivial)默认构造函数。这里的“非平凡”意味着该成员的默认构造函数不是trivial的,也就是说,它执行了除了简单的位复制或位移动之外的操作。如果联合体X中没有任何变体成员有默认成员初始化器(即,没有成员被默认值初始化),那么这个联合体的默认构造函数就会被定义为已删除。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题