C++中的union,POD以及cv-qualified
事实上,我在工作中很少使用union,今天偶尔用了一下,呵呵,问题还真不少,很多细节以前都没有注意到。我查了一下csdn,关于union方面的帖子很少,这篇文章就算是弥补一下空白吧。大家有什么看法,都可以补充一下。
btw:我认为,c++中union的使用应该仅局限于传统的用法,就是类似于下面的用法
typedef unsigned short VARTYPE;
struct _tagMyVariant
{
VARTYPE vt;
union
{
LONG lVal;
BYTE bVal;
...
};
};
正文:
C++中的union,很大程度上是为了兼容C语言才提出来的,看了下面的文章,你就会感觉到,C++中的union显得有些不伦不类。如果需要用到union,我们最好使用传统的union,也就是C中的union。至于下面提到的C++中的union独有的特点,在实际工作中,最好不要用;当然,了解一下还是有好处的,至少和朋友吹牛的时候可以用到,^_^
在C++中,union有以下特点:
1. union可以定义自己的函数,包括 constructor 以及 destructor。
2. union支持 public , protected 以及 private 权限。
读者看到这可能会问,要是这样的话,union与class还有什么区别吗?区别当然还是有的
3. union不支持继承。也就是说,union既不能有父类,也不能作为别人的父类。
4. union中不能定义虚函数。
5. 不是所有类型的变量都能作为union的成员变量。POD(注1)类型可以作为union的成员变量。如果一个类,包括其父类,含有自定义的constructor,copy constructor,destructor,copy assignment operator, virtual function中的任意一个,那么这种类型的变量不能作为union的成员变量(注3)。
6. union中可以定义static以及引用类型的成员变量,不过C++标准不推荐这样做,包含这样代码的程序是ill-formed的
如果我们在定义union的时候没有定义名字,那么这个union被称为匿名union(anonymous union)。匿名union的特点如下:
1. 匿名union中不能定义static变量。
2. 匿名union中不能定义函数。
3. 匿名union中不支持 protected 以及 private 权限。
4. 在全局域以及namespace中定义的匿名union只能是static的。
ok,写道最后,留一个问题给大家:
union {
int aa;
char* p;
}obj;
这里定义的union是不是匿名的union?
注1: 什么是POD?
POD 的全称是 Plain Old Data,在C++标准中,POD是这样定义的:
Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to member types (3.9.2), and cv-qualified(注2) versions of these types (3.9.3) are collectively called scalar types. Scalar types, POD-struct types,POD-union types (clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called POD types.
我们可以这样理解POD,与C兼容的数据类型可以被成为POD类型。
注2:什么是cv-qualified ?
这里的CV分别是const 以及volatile的缩写。用const,volatile以及const volatile之一作修饰的变量被成为cv-qualified ,否则该变量是cv-unqualified
注3:class是不是POD类型?
我觉得class不应算作POD类型,但是如果一个class没有non-trivial 的 constructor, destructor, 以及 copy assignmet operator这些东西的话,这个class事实上已经退化成一个POD类型了,就相当于C中的struct。这样,union中就可以包含你这样的数据类型。也就是说,union可以包含特定的非POD类型变量。不知道大家对此有什么看法?
[解决办法]
C中UNION是用于支持低级内存操作例如WINNT.H很多用到,如:
(块表)
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
使用UNION能增强可读性,同时在C下面看上去比麻烦的位操作舒服
[解决办法]
学习下 以前基本上没用过UNION
长见识 以后自己试一下
[解决办法]
即使是C编程,也应该尽量不要用union
[解决办法]
用,但都是用c的
[解决办法]
只是在用数据库的时候用过.
[解决办法]
呃,反正我是没用过
[解决办法]
没用过 接点分 呵呵
[解决办法]
很少用到
学习
接分
[解决办法]
没用过 顶一下吧
[解决办法]
顶好
[解决办法]
union {
int aa;
char* p;
}obj;
这里定义的union是不是匿名的union?
=================
不是
[解决办法]
【Ref】
匿名union
匿名union是没有名称和声明列表的union,这跟 ' ' ' '__unnamed ' ' ' ' union不是一回事,它的声明形式如下:
union { member-list } ;
匿名union仅仅通知编译器它的成员变量共享一个地址,而变量本身是直接引用的,不使用通常的点号运算符语法.也正因此,匿名union与同一程序块内的其它变量具有相同的作用域级别,需注意命名冲突.
请看下面的例子:
#include <iostream.h>
struct DataForm
{
enum DataType { CharData = 1, IntData, StringData };
DataType type;
// Declare an anonymous union.
union
{
char chCharMem;
char *szStrMem;
int iIntMem;
};
void print();
};
void DataForm::print()
{
// Based on the type of the data, print the
// appropriate data type.
switch( type )
{
case CharData:
cout < < chCharMem;
break;
case IntData:
cout < < szStrMem;
break;
case StringData:
cout < < iIntMem;
break;
}
}
此外,匿名union还具有以下约束:
1).因为匿名联合不使用点运算符,所以包含在匿名联合内的元素必须是数据,不允许有成员函数,也不能包含私有或受保护的成员;
2).全局匿名联合必须是静态(static)的
[解决办法]
以前参与过一个C编译器的项目,感觉匿名union是个挺麻烦的东西。
关于C++中的union,可以参考《Exceptional C++ Style》36条:Construction Unions
[解决办法]
回答楼主,匿名union没有类型名,也不能声明对象,所以不是。