C++ 语言特性12 - 联合体类型
一:概述
C和C++中的联合体概念是类似的,联合体允许在同一个内存位置存储不同的数据类型,即多个对象共享同一片内存。但是,C++11对union
进行了扩展,使其更加灵活和强大。以下是C语言和C++11中union
的主要差异:
1. C语言中的union
:
-
成员限制:C语言中的
union
只能包含POD(Plain Old Data)类型,即不能包含构造函数、析构函数或虚函数的类型。 -
匿名联合体:C语言支持匿名联合体,这允许在结构体中定义没有名字的
union
。 -
大小:
union
的大小等于最大成员的大小。 -
对齐:
union
的对齐方式通常与最大成员的对齐方式相同。 -
构造和析构:C语言中的
union
成员不会自动调用构造函数或析构函数。
2. C++11中的union
:
-
非受限联合体:C++11允许
union
包含非POD类型,包括具有构造函数和析构函数的类。 -
委托构造函数:C++11允许在
union
中使用委托构造函数。 -
静态成员:C++11允许
union
拥有静态成员函数。 -
继承:C++11中的
union
可以继承其他类型,并且可以作为基类。 -
成员函数:
union
可以拥有成员函数,但不能有虚函数。 -
默认构造函数:如果
union
包含非POD类型,其默认构造函数可能会被删除。
二:例子
1. C语言中例子
#include <stdio.h>union Data {int i;float f;char str[20];
};int main() {union Data d;d.i = 42;printf("d.i = %d\n", d.i);// d.f = 3.14; // 也可以选择使用浮点数成员// strcpy(d.str, "Hello, World!"); // 或者使用字符数组成员return 0;
}
2. C++语言的例子
#include <iostream>
#include <string>union Data {int i;double d;std::string s; // 非POD类型Data() : i(0), d(0.0) {} // 默认构造函数
};int main() {Data d;d.i = 42;std::cout << "d.i = " << d.i << std::endl;// d.d = 3.14; // 也可以选择使用浮点数成员// d.s = "Hello, World!"; // 或者使用字符串成员return 0;
}
三:注意事项
-
类型安全:C++11中的
union
提供了更多的类型安全特性,但使用时仍需小心。 -
未定义行为:在
union
的非活跃成员上进行读取操作是未定义行为(union中被存储值的成员被称为活跃成员,而其他没有存储值的成员被称为非活跃成员)。 -
构造和析构:如果
union
包含有构造函数和析构函数的非POD类型,需要手动管理这些成员的构造和析构。 -
C++11特性:使用C++11的
union
特性时,需要确保编译器支持这些特性。