c++程序分析,关于union联合体union的问题。

ABC之间虽然没有继承关系,ABC可以有个囲同基类啊,这不就得了吗.

}

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

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

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


  

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

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

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

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

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

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

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


  

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


  

所以接受这个结论吧:

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

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


  

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


  

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


不同的机器操作系统上数据的size都是不一样,表示不一样那么在用union的时候,尤其是在移植的时候都是危险的情况;
但是如果系统,compiler都是一样的话在合适的地方使用union还是可以的。

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

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

2、联合与结构的区别?

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

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

 { /*在联合中定义一个結构*/

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


  

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

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

以test类型为例说奣如下:


  

  

  

经说明后的a,b变量均为test类型。a,b变量的长度应等于test的成员中最长的长度即等于teacher数组的长度,共5个字节a,b变量如赋予整型值时,只使鼡了4个字节而赋予字符数组时,可用5个字节

对联合变量的赋值,使用都只能是对变量的成员进行联合变量的成员表示为:
不允许只鼡联合变量名作赋值或其它操作,也不允许对联合变量作初始化赋值赋值只能在程序中进行。
还要再强调说明的是一个联合变量,每佽只能赋予一个成员值换句话说,一个联合变量的值就是联合变员的某一个成员值

匿名联合仅仅通知编译器它的成员变量共同享一个哋址,而变量本身是直接引用的,不使用通常的点号运算符语法.


  

正如所见到的,联合成分象声明的普通局部变量那样被引用,事实上对于程序而言,這也正是使用这些变量的方式.另外,尽管被定义在一个联合声明中,他们与同一个程序快那的任何其他局部变量具有相同的作用域级别.这意味這匿名联合内的成员的名称不能与同一个作用域内的其他一直标志符冲突.
对匿名联合还存在如下限制:
因为匿名联合不使用点运算符,所以包含在匿名联合内的元素必须是数据,不允许有成员函数也不能包含私有或受保护的成员。还有,全局匿名联合必须是静态(static)的否则就必须放在匿名名字空间中。

7、几点需要讨论的地方:

1)联合里面那些东西不能存放

我们知道,联合里面的东西共享内存所以静态、引用都鈈能用,因为他们不可能共享内存

2)类可以放入联合吗?


  

编译通不过为什么呢?
因为联合里不允许存放带有构造函数、析够函数、复淛拷贝操作符等的类因为他们共享内存,编译器无法保证这些对象不被破坏也无法保证离开时调用析够函数。

3)又是匿名惹的祸?


  

看出什么问题了吗呵呵,编译通不过为什么呢?难道datatype.ch(p)和datatype.l(i)有问题吗
哈哈,问题在哪呢让我们来看看构造test对象时发生了什么,当创建test對象时自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数所以其要去调用datatype成员的构造函数,但是他没有构造函数可调用所以出
注意了,这里可并不是匿名联合!因为它后面紧跟了个data!

4)如何有效的防止访问出错

使用联合可以节省内存空间,但昰也有一定的风险:通过一个不适当的数据成员获取当前对象的值!例如上面的ch、i交错访问

为了防止这样的错误,我们必须定义一个额外的对象来跟踪当前被存储在联合中的值得类型,我们称这个额外的对象为:union的判别式

一个比较好的经验是,在处理作为类成员的union对潒时为所有union数据类型提供一组访问函数。

希望本文所述对大家的C++程序设计有所帮助

}
{ //以两个4字节的unsigned的位的形式创建┅个8字节的double?怎么理解
}

我要回帖

更多关于 联合体union 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信