c – 使用类似Classes / Structs的联合

当我惊讶地发现以下代码完全有效并且完全符合预期时,我试图更多地了解工会及其实用性:

template <class T>
union Foo
{
    T a;
    float b;

    Foo(const T& value)
        : a(value)
    {
    }

    Foo(float f)
        : b(f)
    {
    }

    void bar()
    {
    }

    ~Foo()
    {
    }
};

int main(int argc, char* argv[])
{
    Foo<int> foo1(12.0f);
    Foo<int> foo2((int) 12);

    foo1.bar();
    foo2.bar();

    int s = sizeof(foo1); // s = 4, correct

    return 0;
}

到目前为止,我不知道使用模板,构造函数,析构函数甚至成员函数声明联合是合法的.如果它是相关的,我正在使用Visual Studio 2012.

当我搜索互联网以找到更多关于以这种方式使用工会的信息时,我一无所获.这是C的新功能,还是MSVC特有的功能?如果没有,我想了解更多关于工会的信息,特别是类似于类的例子(上图).如果有人能够指出我对工会及其作为数据结构的使用的更详细的解释,那将非常感激.

最佳答案

Is this a new feature of C++, or something specific to MSVC?

不,正如BoBtFish所说,2003 C标准第9.5节第1段说:

[…] A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. A union shall not have base classes. A union shall not be used as a base class. An object of a class with a non-trivial constructor (12.1), a non-trivial copy constructor (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment operator (13.5.3, 12.8) cannot be a member of a union, nor can an array of such objects. If a union contains a static data member, or a member of reference type, the program is ill-formed.

联盟确实属于第9节类,类密钥的语法如下:

class-key:
   class
   struct
   union

所以行为就像一个类,但有更多的限制.关键限制是工会一次只能有一个活跃的非静态成员,第1段也对此进行了说明:

In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time. […]

C++11 draft standard中的措辞类似,因此自2003年以来没有太大变化.

至于联合的使用,在前面的线程C/C++: When would anyone use a union? Is it basically a remnant from the C only days?中有两个不同角度涵盖的常见原因总结如下:

>要实现自己的Variant type,联合使您能够表示所有不同类型而不浪费内存. This answer给线程提供了一个很好的例子.
> Type punning但我也会阅读Understanding Strict Aliasing,因为很多情况下类型惩罚是undefined behavior.

这个answerUnions cannot be used as Base class提供了一些非常深刻的见解,为什么工会的实施与C相同.

点赞