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 的使用、创建和访问方式,
- 首先,定义了一个名为 Data 的 union,包含三个成员: 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