结构体为成员分配独立内存,允许同时访问;联合体共享内存,同一时间只能存储一个成员的值。前者适用于需要并存数据的场景,后者节省内存但需谨慎管理活跃成员。

C++中的结构体(struct)和联合体(union)最核心的区别在于它们如何管理和分配内存给其成员。简单来说,结构体为每个成员分配独立的内存空间,允许所有成员同时存在并被访问;而联合体则让所有成员共享同一块内存区域,这块区域的大小足以容纳其最大的成员,因此在任何给定时间,联合体中只有一个成员可以存储有效值。
当我们谈论
struct
int
double
int
double
union
int
double
int
double
double
int
举个例子:
立即学习“C++免费学习笔记(深入)”;
struct MyStruct {
int id;
float value;
char status;
};
union MyUnion {
int id;
float value;
char status;
};
// 假设int和float都是4字节,char是1字节
// sizeof(MyStruct) 可能会是 4 (id) + 4 (value) + 1 (status) + 潜在的填充 = 12字节或更多。
// sizeof(MyUnion) 会是 max(sizeof(int), sizeof(float), sizeof(char)) = 4字节。可以看到,在内存占用上,联合体有着天然的优势。
这是一个非常棒的问题,它触及了C++设计哲学的核心:提供强大的底层控制能力和极致的效率。虽然
union
首先,最主要的原因是内存效率。在资源受限的环境中,比如嵌入式系统、物联网设备,甚至是追求极致性能的高性能计算领域,每一字节内存都弥足珍贵。
union
struct
union
其次,
union
std::variant
union
std::variant
union
此外,在某些低级编程场景中,
union
float
int
memcpy
std::bit_cast
union
因此,尽管
union
安全使用
union
struct
以下是这种模式的示例:
enum class MessageType {
TEXT_MESSAGE,
IMAGE_MESSAGE,
AUDIO_MESSAGE
};
struct TextData {
char content[256];
int length;
};
struct ImageData {
int width;
int height;
unsigned char* pixelData; // 简化示例,实际可能更复杂
};
struct AudioData {
int sampleRate;
int channels;
short* samples; // 简化示例
};
struct Message {
MessageType type; // 判别器:指示当前活跃的类型
union {
TextData text;
ImageData image;
AudioData audio;
} data; // 实际的联合体
};
// 使用示例:
Message msg;
msg.type = MessageType::TEXT_MESSAGE;
// 写入文本数据
strncpy(msg.data.text.content, "Hello World!", sizeof(msg.data.text.content) - 1);
msg.data.text.content[sizeof(msg.data.text.content) - 1] = '\0'; // 确保null终止
msg.data.text.length = strlen(msg.data.text.content);
// 稍后处理消息时:
switch (msg.type) {
case MessageType::TEXT_MESSAGE:
// 安全地访问 msg.data.text
std::cout << "Text Message: " << msg.data.text.content << std::endl;
break;
case MessageType::IMAGE_MESSAGE:
// 安全地访问 msg.data.image
std::cout << "Image Message (width: " << msg.data.image.width << ")" << std::endl;
break;
case MessageType::AUDIO_MESSAGE:
// 安全地访问 msg.data.audio
std::cout << "Audio Message (sample rate: " << msg.data.audio.sampleRate << ")" << std::endl;
break;
}在这个设置中,
type
union
type
union
type
另一个关键点是,如果你的联合体成员不是POD (Plain Old Data) 类型(即它们拥有自定义的构造函数、析构函数或赋值运算符),你需要格外小心。在C++11之前,联合体只能包含POD类型。从C++11开始,允许非POD类型,但程序员有责任手动调用活跃成员的构造函数和析构函数。这是一个复杂且容易出错的过程。现代C++(C++17及更高版本)提供的
std::variant
union
内存对齐和填充是数据在内存中如何布局的两个重要概念,它们对
struct
union
对于struct
int
考虑以下示例:
struct ExampleStruct {
char a; // 1字节
int b; // 4字节,需要4字节对齐
char c; // 1字节
};
// 在一个32位系统上(int通常为4字节):
// 'a' 占用1字节。
// 接下来可能会插入3字节的填充,以使'b'对齐到4字节边界。
// 'b' 占用4字节。
// 'c' 占用1字节。
// 结构体末尾可能会再插入3字节的填充,以确保整个ExampleStruct的大小是4的倍数(最大对齐要求)。
// 最终sizeof(ExampleStruct) 可能是 1 + 3 (填充) + 4 + 1 + 3 (填充) = 12字节。这种填充对于性能至关重要,但它也意味着结构体的实际大小可能大于其所有成员原始大小的总和。
而对于union
union
示例:
union ExampleUnion {
char a; // 1字节
int b; // 4字节,需要4字节对齐
double d; // 8字节,需要8字节对齐
};
// 在一个典型系统上:
// 最严格的对齐要求是'double',即8字节。
// 最大的成员也是'double'(8字节)。
// 因此,sizeof(ExampleUnion) 将是8字节。它将对齐到8字节边界。
// 如果没有'double',且'int'是最大的(4字节),那么大小将是4字节。union
a
b
d
以上就是C++联合体结构体区别 内存共享机制对比的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号