union

  • 这是一个十分经典的地数据类型,可以最大程度上利用现有的空间,并增强的代码的灵活性
  • 想必对编程有些的认知的小伙伴们,或多或少对此都有着一些接触
  • 今天就让我们简单聊聊那些你在使用过程并不会注意到的点吧
  1. union的大小,取决于最大的那个
  2. union的指定初始化
    1
    2
    3
    4
    5
    6
    7
    union data {
    int a;
    float b;
    }instance;

    // 当然这种初始化方式同样也适用于结构体
    instance { .a = 0};
  3. union支持非平凡的数据类型
  • 这是我们今天在再聊union的一个核心目的。
  • 自C++11之后,引入的非平凡类型,拓宽了其使用场景。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    // 与此同时,引入了一个问题便是,我们需要为撰写构造与析构函数
    // 下述代码,可正常,却无法运行。因为默认的构造、析构,无法很好地处理下面的非平凡类型
    union U {
    U() {}
    ~U() {}
    int x1;
    float x2;
    std::string x3;
    std::vector<int> x4;
    }

    // 那这样写如何呢?
    // 答案显然是不行的,编译器无从得知我们需要初始化那个成员
    union U {
    U() : x3() {}
    ~U() { x3.~basic_string()}
    int x1;
    float x2;
    std::string x3;
    std::vector<int> x4;
    }

    // 最优做法
    union U {
    U() {}
    ~U() {}
    int x1;
    float x2;
    std::string x3;
    std::vector<int> x4;
    }

    // 采用了palcement new的技巧,解决了这个问题
    int main() {
    U u;
    new(&u.x3) std::string("hello world");
    u.x3.~basic_string();

    new(&u.x4) std::vector<int>;
    u.x4.~vector();

    return 0;
    }
    4.union支持静态成员,不过同类一样,他不属于对象,故不能在其中初始化