C++ 中的联合体



在 C++ 中,**联合体 (union)** 是一种用户定义的数据类型,允许您在同一内存位置存储不同的数据类型。但是,联合体一次只能存储其一个成员变量,这意味着如果您为一个成员赋值,则之前存储在另一个成员中的值将被覆盖。其中联合体的大小由其最大成员的大小决定。

联合体声明

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

以下是声明联合体的语法:

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

示例

这是一个基于上述语法声明联合体的简短示例:

union UnionName {
  int intValue;     // Member for integer value
  float floatValue; // Member for float value
  char charValue;   // Member for character value
};

声明联合体变量

声明联合体后,您需要声明其变量以访问和操作其成员。

以下是声明联合体变量的语法:

union_name variable;

访问联合体成员

您可以使用点运算符 (.) 在声明联合体变量后访问联合体成员。

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

union_variable.member

C++ 联合体示例

这是一个联合体的完整示例,演示了它的工作原理:

#include <iostream>
#include <cstring>

using namespace std;

union Data {
  int intValue; // Member for integer value
  float floatValue; // Member for float value
  char strValue[50]; // Member for string value
};

int main() {
  // Defining a union variable
  Data data;

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

  // overwrites the previous integer value
  data.floatValue = 5.75f;
  cout << "My Float value is: " << data.floatValue << endl;

  // overwrites the previous float value
  strcpy(data.strValue, "Hello TutorialsPoint Learner");
  cout << data.strValue << endl;

  // Accessing the integer after assigning a string
  cout << "Integer after string assignment: " << data.intValue << endl;
  // Undefined behavior

  return 0;
}

当以上代码编译并执行时,会产生以下结果:

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

解释

以上示例演示了联合体的用法,如何创建和访问它。

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

匿名联合体

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

语法

这是一个匿名联合体的简单语法,它在声明时没有名称,允许直接访问其成员:

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

示例

这是一个基于上述语法的匿名联合体示例:

#include <iostream>

#include <cstring>

using namespace std; // Use the standard namespace

int main() {
  // Anonymous union declaration
  union {
    int intValue;
    float floatValue;
    char strValue[50];
  };

  // Assigning an integer value
  intValue = 2006;
  cout << "Integer Value: " << intValue << endl;

  // Assigning a float value (overwrites the previous integer value)
  floatValue = 3.14 f;
  cout << "Float Value: " << floatValue << endl;

  // Assigning a string value (overwrites the previous float value)
  strcpy(strValue, "Hello, TutorialsPoint Learner!");
  cout << "String Value: " << strValue << endl;

  // Accessing the integer after string assignment (undefined behavior)
  cout << "Integer after string assignment: " << intValue << endl;

  return 0;
}

当以上代码编译并执行时,会产生以下结果:

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

类似联合体的类

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

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

语法

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

class UnionLikeClass {
public:
  union {
    dataType1 member1;  // Member of type dataType1
    dataType2 member2;  // Member of type dataType2
    // additional members...
  };
};

示例

这是一个基于上述语法的类似联合体的类示例

#include <iostream>

#include <cstring>

using namespace std;

class UnionLikeClass {
  public:
    // Anonymous union declaration
    union {
      int intValue; // Member for integer value
      float floatValue; // Member for float value
      char strValue[50]; // Member for string value
    };

  // Method to display the current value
  void display() {
    cout << "Integer Value: " << intValue << endl;
    cout << "Float Value: " << floatValue << endl;
    cout << "String Value: " << strValue << endl;
  }
};

int main() {

  // Creating an instance of UnionLikeClass
  UnionLikeClass data;

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

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

  // Assigning a string value (overwrites the previous float value)
  strcpy(data.strValue, "Hello, Union Like Class!");
  cout << "Assigned String Value: " << data.strValue << endl;

  // Accessing the integer after string assignment (undefined behavior)
  cout << "Integer after string assignment: " << data.intValue << endl;
  // Undefined behavior

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