C++ union怎么用?联合体定义和使用详解?

文章导读
上一个 测验 下一个 In C++, union 是一种用户定义的数据类型,它允许你在同一内存位置存储不同的数据类型。然而,union 一次只能存储其一个成员变量的值,这意味着如果你给一个成员赋值,则之前存储在另一个成员中的值将被覆盖。union 的大小由其最大成员的大小决
📋 目录
  1. 联合声明
  2. 声明联合变量
  3. 访问联合成员
  4. C++ 联合示例
  5. 匿名联合
  6. 类似联合的类
A A

C++ 中的联合



上一个
测验
下一个

In C++, union 是一种用户定义的数据类型,它允许你在同一内存位置存储不同的数据类型。然而,union 一次只能存储其一个成员变量的值,这意味着如果你给一个成员赋值,则之前存储在另一个成员中的值将被覆盖。union 的大小由其最大成员的大小决定。

联合声明

要声明一个 union,使用 union 关键字,后跟 tag_name(联合名称),然后在大括号内使用其数据类型声明联合成员。以分号结束声明。

以下是声明 union 的语法 −

union UnionName {
  dataType1 member1;
  dataType2 member2;
  // more members
};

示例

以下是基于上述语法的声明 union 的简短示例 −

union UnionName {
  int intValue;     // 用于整数值的成员
  float floatValue; // 用于浮点值的成员
  char charValue;   // 用于字符值的成员
};

声明联合变量

声明 union 后,你需要声明其变量以访问和操作其成员。

以下是声明 union 变量的语法 −

union_name variable;

访问联合成员

声明 union 变量后,可以使用点运算符 (.) 访问 union 成员。 

以下是访问联合成员的语法 -

union_variable.member

C++ 联合示例

以下是一个完整的 union 示例,演示其工作原理 −

#include <iostream>
#include <cstring>

using namespace std;

union Data {
  int intValue; // 用于整数值的成员
  float floatValue; // 用于浮点值的成员
  char strValue[50]; // 用于字符串值的成员
};

int main() {
  // 定义一个联合变量
  Data data;

  data.intValue = 2006;
  cout << ": Founded in " << data.intValue << endl;

  // 覆盖之前的整数值
  data.floatValue = 5.75f;
  cout << "My Float value is: " << data.floatValue << endl;

  // 覆盖之前的浮点值
  strcpy(data.strValue, "Hello  Learner");
  cout << data.strValue << endl;

  // 在赋值字符串后访问整数
  cout << "Integer after string assignment: " << data.intValue << endl;
  // 未定义行为

  return 0;
}

上述代码编译并执行后,将产生以下结果 −

: Founded in 2006
My Float value is: 5.75
Hello  Learner
Integer after string assignment: 1819043144

解释

上述示例演示了 union 的使用、创建和访问方式,

  • 首先,定义了一个名为 Dataunion,包含三个成员: int intValue, float floatValue, char strValue[50],其中这些成员在任意时刻只能有一个持有值。 
  • union 的大小由最大成员决定,因此在本例中为(字符数组)。
  • int main() 函数体内声明了一个 union 变量 data
  • 为了赋值和访问成员,所有成员都使用 "." 运算符为其赋值,如 data.intValue
  • 对于浮点值,将浮点成员 floatValue 赋值为 5.75。
  • 然而,由于 union 一次只能持有一个值,之前的 intValue 值将被覆盖,尽管它仍占用相同的内存空间。
  • 最后,当代码尝试在被字符串赋值覆盖后打印 intValue 时。这会导致 undefined behavior,整数值不再有效,访问它可能会产生输出中所示的意外结果。

匿名联合

匿名联合是一种特殊的联合类型,它没有名称。这种设计通过允许直接访问联合成员而无需指定联合变量名,来简化代码。

语法

以下是匿名联合的简单语法,它不带任何名称声明,从而允许直接访问其成员 −

union {
  dataType1 member1;
  dataType2 member2;
  // additional members...
};

示例

以下是基于上述语法的匿名联合示例 −

#include <iostream>

#include <cstring>

using namespace std; // 使用标准命名空间

int main() {
  // 匿名联合声明
  union {
    int intValue;
    float floatValue;
    char strValue[50];
  };

  // 赋整数值
  intValue = 2006;
  cout << "Integer Value: " << intValue << endl;

  // 赋浮点值(覆盖之前的整数值)
  floatValue = 3.14 f;
  cout << "Float Value: " << floatValue << endl;

  // 赋字符串值(覆盖之前的浮点值)
  strcpy(strValue, "Hello,  Learner!");
  cout << "String Value: " << strValue << endl;

  // 在字符串赋值后访问整数(未定义行为)
  cout << "Integer after string assignment: " << intValue << endl;

  return 0;
}

上述代码编译并执行后,将产生以下结果 −

Integer Value: 2006
Float Value: 3.14
String Value: Hello,  Learner!
Integer after string assignment: 1819043144

类似联合的类

在 C++ 中,类似联合的类被定义为包含至少一个匿名联合作为成员的类。这些匿名联合中定义的数据成员被称为变体成员。它是封装联合概念的数据结构,但提供了类型安全和可用性的额外特性。

这些通常结合成员变量和一种机制(如枚举器)来跟踪当前活动的类型。

语法

以下是类似联合类的基本语法,其中使用class关键字定义类,后跟类名(此处为 UnionLikeClass)

class UnionLikeClass {
public:
  union {
    dataType1 member1;  // 类型为 dataType1 的成员
    dataType2 member2;  // 类型为 dataType2 的成员
    // additional members...
  };
};

示例

以下是基于上述语法的类似联合类的示例:

#include <iostream>

#include <cstring>

using namespace std;

class UnionLikeClass {
  public:
    // 匿名联合声明
    union {
      int intValue; // 用于整数值的成员
      float floatValue; // 用于浮点值的成员
      char strValue[50]; // 用于字符串值的成员
    };

  // 显示当前值的方法
  void display() {
    cout << "Integer Value: " << intValue << endl;
    cout << "Float Value: " << floatValue << endl;
    cout << "String Value: " << strValue << endl;
  }
};

int main() {

  // 创建 UnionLikeClass 的实例
  UnionLikeClass data;

  data.intValue = 2006;
  cout << ": Founded in " << data.intValue << endl;

  data.floatValue = 3.14f;
  cout << "Assigned Float Value: " << data.floatValue << endl;

  // 赋字符串值(覆盖之前的浮点值)
  strcpy(data.strValue, "Hello, Union Like Class!");
  cout << "Assigned String Value: " << data.strValue << endl;

  // 在字符串赋值后访问整数(未定义行为)
  cout << "Integer after string assignment: " << data.intValue << endl;
  // 未定义行为

  return 0;
}
: Founded in 2006
Assigned Float Value: 3.14
Assigned String Value: Hello, Union Like Class!
Integer after string assignment: 1819043144