|
在上面的示例中,任何访问 union 的代码都需要了解保存数据的成员。 解决此问题的最常见解决方案被称为“可区分 union”。 它将 union 括在 struct 中,还加入一个 enum 成员,用于指示当前存储在 union 中的成员类型。 下面的示例演示了基本模式:
C++
复制
#include <queue>
using namespace std;
enum class WeatherDataType
{
Temperature, Wind
};
struct TempData
{
int StationId;
time_t time;
double current;
double max;
double min;
};
struct WindData
{
int StationId;
time_t time;
int speed;
short direction;
};
struct Input
{
WeatherDataType type;
union
{
TempData temp;
WindData wind;
};
};
// Functions that are specific to data types
void Process_Temp(TempData t) {}
void Process_Wind(WindData w) {}
void Initialize(std::queue<Input>& inputs)
{
Input first;
first.type = WeatherDataType::Temperature;
first.temp = { 101, 1418855664, 91.8, 108.5, 67.2 };
inputs.push(first);
Input second;
second.type = WeatherDataType::Wind;
second.wind = { 204, 1418859354, 14, 27 };
inputs.push(second);
}
int main(int argc, char* argv[])
{
// Container for all the data records
queue<Input> inputs;
Initialize(inputs);
while (!inputs.empty())
{
Input const i = inputs.front();
switch (i.type)
{
case WeatherDataType::Temperature:
Process_Temp(i.temp);
break;
case WeatherDataType::Wind:
Process_Wind(i.wind);
break;
default:
break;
}
inputs.pop();
}
return 0;
}
在上面的示例中,Inputstruct 中的 union 没有名称,因此被称为“匿名 union”。 它的成员是可以直接访问的,就像它们是 struct 的成员一样。 有关如何使用匿名 union 的详细信息,请参阅“匿名 union”部分。
上面的示例展示的问题也可以通过以下方法解决:使用派生自公共基 class 的 class 类型。 基于容器中每个对象的运行时类型对代码进行分支。 代码将更易于维护和理解,但是也可能比使用 union 更慢。 此外,通过 union 可以存储不相关的类型。 union 让你可以动态地更改存储值的类型,而无需更改 union 变量本身的类型。 例如,可以创建其元素存储不同类型的不同值的 MyUnionType 异类数组。
很容易误用示例中的 Inputstruct。 由用户负责正确使用鉴别器来访问保存数据的成员。 你可以通过使 union 成为 private 并提供特殊访问函数(如下一个示例所示)来防止误用。
|
|