繁体   English   中英

铸造工会

[英]Casting to union

由于在C ++中使用union的经验有限,我正在努力理解向/从该数据类型转换的基本机制。

假设Type_aType_b两种类型Type_aintlong类型的包装器。

联合定义为:

union Type_u {
    Type_a a;
    Type_b b;
}

现在我有类型Type_a东西,让我们称之为j (只是让人困惑)。 我需要将它传递给一个期望Type_u类型的参数的Type_u

void burninate(Type_u peasants);

将此变量j传递给burninate的正确方法是什么? (我遇到了将jType_u以及按原样传递它的问题。都没有编译。)

值得指出的是,我没有能力修改联合类型(或Type_a或Type_b或者burninate的签名)。

由于Type_a是第一个元素,您可以像这样初始化一个联合:

Type_a j;
Type_u u = {j};
burninate(u);

如果要传递Type_b类型:

Type_b k;
Type_u u;
u.b = k;
burninate(u);

C和C ++在这方面有所不同。 在C99中,您可以使用指定的初始化程序来初始化不是第一个的元素。

Type_b k;
Type_u u = {.b = k};
burninate(u);

你可以像这样传递j ((Type_u)j) ,它会起作用。

[编辑]由于这些家伙表示不相信,这里是代码示例尝试编译此代码,它将像魅力一样工作。

#include <stdio.h>
typedef union type_u {
    int a;
    long b;
}type;

int main ()
{
type T;
int j = 10;

    T = ((type)j);

    printf ("T.a:%d T.b:%lu \n", T.a, T.b);

return 0;
}

参见o / p XXX-mac:~jork $ gcc union_test.c XXX-mac:~jork $ ./a.out Ta:10 Tb:10

C ++通常不会鼓励使用联合,如果union成员有非平凡的构造函数和析构函数,它可能会特别尴尬,因为在这种情况下,union的自己的构造函数(分别是析构函数)将被删除,你需要自己提供一个(你通常会这样做)。

总的来说,将非POD类型放入联合可能不是一个好主意,因为语义很笨拙; 一般来说,你不能为一个尚未构造的对象赋值,并且,虽然你可以使用placement new来构造一个union的成员,但是你无法真正知道该成员之前没有被构造过。 。 此外,如果一个成员有一个明确的,非平凡的析构函数,你可以为union提供一个显式的析构函数,它可以显式地调用成员的析构函数,但是如何知道它是否必须这样做呢?

但是,如果您的工会成员是POD,那么您很好,但您仍然无法将工会转换为工会的成员或成员类型。 (GCC允许将其作为C扩展,但afaik g++不会以相同的方式扩展C ++。)

尽管如此,没有什么可以阻止你给union一个构造函数。 例如:

union long_or_double {
  long a;
  double d;

  long_or_double(long l) : a(l) {}
  long_or_double(int i) : a(i) {}
  // etc.
  long_or_double(double d) : d(d) {}
};

int f(long_or_double u);

int main(int argc, char** argv) {
  // Both of these work, because there is an explicit constructor
  f(argc);
  f(3.7);
  // ...
}

如果你不能在union类型的定义中添加构造函数,我认为你能做的最好的事情是定义一个make_union函数,为每个成员类型适当地覆盖它。

联合的工作方式与结构完全相同(唯一的区别是对象在内存中的分配方式)。 所以你有Type_u U; Type_a j; Ua = j; 博恩奈特(U);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM