在OOP中使用Union

时间:2012-05-05 15:17:19

标签: c++ language-lawyer unions

Unions可以像类和结构一样用作类型(有一些限制)。它可以有成员函数。它可以用作OOP构造。

据我所知,工会刚刚被导入到C ++中以保持与C的向后兼容性 在这些编程的这些年里,我从来没有使用像我将类或结构作为OOP结构的联合。

是否有任何实际使用Union作为OOP构造(不仅仅是作为数据类型),或者它只是该语言的一些残留部分,从来没用过?


修改
该标准肯定允许union作为OOP构造。它允许联合中的成员函数。以下代码编译和工作,并符合标准:

union A
{
    int a;
    int k;

    void doSomething(){}

};

int main()
{
    A obj;
    int i = obj.a;
    obj.doSomething();
    return 0;
}

为什么标准允许成员函数在一个联合中,如果它不应该作为一个OOP结构呢? 请用特定的推理发布答案,请不要发表答案我不这么认为,没有一个很好的理由为什么?

6 个答案:

答案 0 :(得分:4)

,联合不是OO构造。

OO最重要的一个特性是多态性,但是联合不能参与继承关系(不能是不同类型的基础,不能有基础本身)或具有虚函数。联合的唯一目的是提供数据类型,而不是对象

答案 1 :(得分:1)

我的个人观点是“不”。

从历史上看,C允许开发人员对主机系统进行低级访问,以非常灵活的方式访问内存。通过提供一个构造来将相同的内存区域视为不同的数据类型,这种灵活性变得更加容易。

但很难看出这可以归类为任何类型的面向对象的构造。

答案 2 :(得分:1)

我认为没有

工会面向对象无关。

C ++从未说它只打算支持OO。 C ++支持从开始多范式(同时:程序,功能,生成,面向对象)

C ++ 11支持“不受限制的工会”,但我从OO的角度看不出任何用法

取决于作者面向对象需要以下问题:

  • 身份
  • 继承/一般主义
  • polymorphy
  • 封装

如果工会,第一个问题有效。 可以识别联合(例如,通过其地址)

联盟没有继承的概念。

有人可能认为数据在联合中是多态的,但这种解释远非oo认为是多态的。 如果没有继承,联合就不能拥有几乎无用的虚函数。 它会破坏内存布局。

联合中有封装。 但是,由于限制,我不希望这种情况下有用的应用程序。 如果有的话我会欣赏一个链接

通过这组功能,我认为“抽象数据类型”(ADA)是正确的术语。

答案 3 :(得分:1)

这不是一个好习惯,但假设您可以强有力地保证只有一个字段可以激活:

class multi_type {
private:
    bool unit_is_float;
    union {
        float float_member;
        int int_member;
    };
public:
    multi_type(bool is_float) : unit_is_float(is_float) {}
    bool isFloat() { return unit_is_float; }
    bool isInt() { return !unit_is_float; }
    float& getFloat() {
        if (!isFloat()) throw std::logic_error("not a float");
        return float_member;
    }
    int& getInt() {
        if (!isInt()) throw std::logic_error("not an int");
        return int_member;
    }
};

格式化为简洁,不漂亮。

有效的应用程序可能在某种解析库中,其中要解析的语言可以具有不同类型的令牌,这些令牌只能在运行时确定。它是使用void * s的替代方法。

答案 4 :(得分:1)

来自Microsoft help

  

C ++ union是类类型的有限形式。它可以包含访问权限   说明符(public,protected,private),成员数据和成员   函数,包括构造函数和析构函数。它不能包含   虚函数或静态数据成员。它不能用作基础   class,也不能有基类。 a。中成员的默认访问权限   工会是公开的。

甚至可以对联合进行模板化(参见例如Templates - The Complete Guide)。从这个意义上讲,工会提供的封装几乎相同

尽管存在所有这些语法限制,但工会确实填补了一个破解C ++类型系统的小漏洞。考虑这些松散的对应关系:

class/struct with virtual functions    <--> dynamic_cast
class/struct without virtual functions <--> static_cast
union                                  <--> reinterpret_cast

多态性就是以安全可控的方式打破类型系统。类和结构会破坏类型系统及时。使用虚函数,我们可以在运行时打破类型系统;没有虚函数,我们可以在编译时完成(特别是使用模板)。另一方面,工会可以打破类型系统到位。请注意,多态性和封装是相辅相成的:任何易于更改的内容都是对用户隐藏的(通过vtable,编译时查找或数据重新解释)。

这是否足以将工会标记为OO编程风格的一部分,这对我来说似乎很有趣。

答案 5 :(得分:0)

如果您的数据具有基于上下文的不同解释和类型,那么作为低级构造,union会很有用。从这个意义上讲,它可以帮助您保持对象的小小,而不是保留不同的字段,这些字段不能同时存在。

这是OOP的有效关注吗?有点,我猜...

-

人们用它们做的一个黑客是访问具有不同名称的不同字节(典型示例是具有4字节r,g,b,a和一个32位整数颜色的并集),但这是潜在危险的{{3 }}