• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++联合体union用法实例详解

C++联合体union用法实例详解

作者:巫祝 字体:[增加 减小] 来源:互联网 时间:2017-05-28

巫祝 通过本文主要向大家介绍了c++ union,c++ union用法,c++指针详解,c++编程实例详解,c++关键字详解等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文实例讲述了C++联合体union用法。分享给大家供大家参考。具体如下:

我们应该按照C中的convention去使用union,这是我这篇文章要给出的观点。虽然C++使得我们可以扩展一些新的东西进去,但是,我建议你不要那样去做,看完这篇文章之后,我想你大概也是这么想的。

  C由于没有类的概念,所有类型其实都可以看作是基本类型的组合,因此在union中包含struct也就是一件很自然的事情了,到了C++之后,既然普遍认为C++中的struct与class基本等价,那么union中是否可以有类成员呢?先来看看如下的代码:

struct TestUnion
{
    TestUnion() {}
};

typedef union
{
    TestUnion obj;
} UT;

int main (void)
{
    return 0;
}

</div>

  编译该程序,我们将被告知:
  error C2620: union '__unnamed' : member 'obj' has user-defined constructor or non-trivial default constructor

  而如果去掉那个什么也没干的构造函数,则一切OK。

  为什么编译器不允许我们的union成员有构造函数呢?我无法找到关于这个问题的比较权威的解释,对这个问题,我的解释是:

   如果C++标准允许我们的union有构造函数,那么,在进行空间分配的时候要不要执行这个构造函数呢?如果答案是yes,那么如果TestUnion 的构造函数中包含了一些内存分配操作,或者其它对整个application状态的修改,那么,如果我今后要用到obj的话,事情可能还比较合理,但是如果我根本就不使用obj这个成员呢?由于obj的引入造成的对系统状态的修改显然是不合理的;反之,如果答案是no,那么一旦我们今后选中了obj来进行 操作,则所有信息都没有初始化(如果是普通的struct,没什么问题,但是,如果有虚函数呢?)。更进一步,假设现在我们的union不是只有一个 TestUnion obj,还有一个TestUnion2 obj2,二者均有构造函数,并且都在构造函数中执行了一些内存分配的工作(甚至干了很多其它事情),那么,如果先构造obj,后构造obj2,则执行的 结果几乎可以肯定会造成内存的泄漏。

  鉴于以上诸多麻烦(可能还有更多麻烦),在构造union时,编译器只负责分配空间,而不负责去执行附加的初始化工作,为了简化工作,只要我们提供了构造函数,就会收到上面的error。

同理,除了不能加构造函数,析构函数/拷贝构造函数/赋值运算符也是不可以加。

  此外,如果我们的类中包含了任何virtual函数,编译时,我们将收到如下的错误信息:
  error C2621: union '__unnamed' : member 'obj' has copy constructor

  所以,打消在union中包含有构造函数/析构函数/拷贝构造函数/赋值运算符/虚函数的类成员变量的念头,老老实实用你的C风格struct吧!
  不过,定义普通的成员函数是OK的,因为这不会使得class与C风格的struct有任何本质区别,你完全可以将这样的class理解为一个C风格的struct + n个全局函数。

  现在,再看看在类中包含内部union时会有什么不同。看看下面的程序,并请注意阅读程序提示:

class TestUnion
{
    union DataUnion
    {
      DataUnion(const char*);
      DataUnion(long);
      const char* ch_;
      long l_;
    } data_;

  public:
    TestUnion(const char* ch);
    TestUnion(long l);
};

TestUnion::TestUnion(const char* ch) : data_(ch) // if you want to use initialzing list to initiate a                                nested-union member, the union must not be anonymous and                              must have a constructor。
{}

TestUnion::TestUnion(long l) : data_(l)
{}

TestUnion::DataUnion::DataUnion(const char* ch) : ch_(ch)
{}

TestUnion::DataUnion::DataUnion(long l) : l_(l)
{}

int main (void)
{
    return 0;
}

</div>

  正如上面程序所示,C++中的union也可以包含构造函数,但是,这虽然被语言所支持,但实在是一种不佳的编程习惯,因此,        我不打算对上面的程序进行过多的说明。我更推荐如下的编程风格:

class TestUnion
{
    union DataUnion
    {
      const char* ch_;
      long l_;
    } data_;
  
  public:
    TestUnion(const char* ch);
    TestUnion(long l);
};

TestUnion::TestUnion(const char* ch)
{
    data_.ch_ = ch;
}

TestUnion::TestUnion(long l)
{
    data_.l_ = l;
}

int main (void)
{
    return 0;
}

</div>

它完全是C风格的。

所以,接受这个结论吧:

请按照C中的convention去使用union,尽量不要尝试使用任何C++附加特性。

union是个好东西,union是个struct,里面所有成员共享一块内存,大小由size最大的member决定,存取成员的时候会以成员的类型来解析这块内存;在gamedev中,union可以在这些方面有所作为:

1. 换名:

struct Rename
{
  public:
    union
    {
      struct 
      {
        float x,y,z,w;
      };
      struct
      {
        float vec[4];
      };
    };
};
</div>

 这样我们既可以根据具体的含义来访问变量,也可以象数组一样的loop;

 2 .压缩:

struct Compression
{
 public:
   bool operator==(const Compression& arg) const { return value == arg.value; }
   union
   {
     struct 
     {
       char a,b,c,d,e,f,g;
     };
     struct
     {
       long long value;
     };
   };
};
</div>

这样对于集中处理的情况,比如==,就会大幅度提高效率,象在64位机上,只要一次,或者传输数据的情况,压缩解压缩都非常方便;

3. 危险:

匿名的union用法,不是standard,所以在compiler上要确认==>编译器移植性不好;
不同的机器操作系统上数据的size都是不一样,表示不一样,那么在用union的时候,尤其是在移植的时候,都是危险的情况;
但是如果系统,compiler都是一样的话,在合适的地方使用union还是可以的。

联合(union)在C/C++里面见得并不多,但是在一些对内存要求特别严格的地方,联合又是频繁出现,那么究竟什么是联合、怎么去用、有什么需要注意的地方呢?就这些问题,我试着做一些简单的回答,里面肯定还有不当的地方,欢迎指出!

1、什么是联合?

“联合”是一种特殊的类,也是一种构造类型的数据结构。在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,已达到节省空间的目的(还有一个节省空间的类型:位域)。 这是一个非常特殊的地方,也是联合的特征。另外,同struct一样,联合默认访问权限也是公有的,并且,也具有成员函数。

2、联合与结构的区别?

“联合”与“结构”有一些相似之处。但两者有本质上的不同。在结构中各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和(空结构除外,同时不考虑边界调整)。而在“联合”中,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。应该说明的是, 这里所谓的共享不是指把多个成员同时装入一个联合变量内, 而是指该联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值。

下面举一个例了来加对深联合的理解。

例4:

#include <stdio.h>
void main()
{
  union number
  { /*定义一个联合*/
   int i;
   struct
   { /*在联合中定义一个结构*/
    char first;
    char second;
   }half;
  }num;
  num.i=0x4241; /*联合成员赋值*/
  printf("%c%c\n", num.half.first, num.half.second);
  num.half.first='a'; /*联合中结构成员赋值*/
  num.half.second='b';
  printf("%x\n", num.i);
  getchar();
}
</div>

输出结果为:

AB
6261

从上例结果可以看出: 当给i赋值后, 其低八位也就是first和second的值; 当给first和second赋字符后, 这两个字符的ASCII码也将作为i 的低八位和高八位。

3、如何定义?

例如:

union test
{
  test() { }
  int office;
  char teacher[5];
};
</div>

定义了一个名为test的联合类型,它含有两个成员,一个为整型,成员名office;另一个为字符数组,数组名为teacher。联合定义之后,即可进行联合变量说明,被说明为test类型的变量,可以存放整型量office或存放字符数组teacher。

4、如何说明?

联合变量的说明有三种形式:先定义再说明、定义同时说明和直接说明。

以test类型为例,说明如下:
1)

union test
{
  int office;
  char 



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++联合体union用法实例详解

相关文章

  • 2017-05-28浮点数在计算机中存储方式是怎样的
  • 2017-05-28C++基础教程之指针拷贝详解
  • 2017-05-28c++中的4种类型转化方式详细解析
  • 2017-05-28c++作用域运算符用法(全局变量和局部变量)
  • 2017-05-28详解C++编程中用数组名作函数参数的方法
  • 2017-05-28C++封装线程类的实现方法
  • 2017-05-28浅谈C++重载、重写、重定义
  • 2017-05-28构造函数定义为private或者protected的好处
  • 2017-05-28C/C++实现对STORM运行信息查看及控制的方法
  • 2017-05-28C++形参与实参的区别实例解析

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Visual C++中MFC消息的分类
    • 利用C++实现从std::string类型到bool型的转换
    • 引用numpy出错详解及解决方法
    • C++和java设计模式之单例模式
    • C++中函数的用法小结
    • C++通过COM接口操作PPT
    • 递归形式与非递归形式的斐波那契数列的用法分析
    • c++实现通用参数解析类示例
    • 用C++实现,将一句话里的单词进行倒置的方法详解
    • C++中引用的使用总结

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有