从Java到C++——union的用法

你是否记得union这个东西,在上大学的时候我们用的是潭浩强的《C语言程序设计》,里面把它译作是共用体。“共用体”,虽然翻译得特别别扭,但却正好说明了它的特性和用途。

联合union,也有翻译成共用体的是一种特殊的结构(或说类)。一个union可以有多个数据成员,但是在任意时刻只有一个成员有值。Union具有以下几个特点:

1.一个union可以有多个不同类型的数据成员, 但在某一时刻只有一个成员有值(即只有一个成员是有效的) 给union的某个成员赋值后,该union的其它成员就成未定义的状态了。如下示例:

// 测试1
union Token
{
    char cVal;      //char 类型
    int nVal;       //int类型
    double dVal;    //double类型
};

void PrintToken(const Token& t)
{
    cout << "char:   " << t.cVal << endl;
    cout << "int:    " << t.nVal << endl;
    cout << "double: " << t.dVal << endl;
}

void TestUnion1()
{
    cout << "Print first:"<< endl;
    Token t;
    t.cVal = ‘k‘;
    PrintToken(t);

    cout << endl << "Print second:"<< endl;
    t.nVal = 5;
    PrintToken(t);
    cout << endl;

    cout << endl << "Print third:"<< endl;
    t.dVal = 10.2;
    PrintToken(t);
}

结果如下:

2.分配给一个union对象的存储空间,至少要能容纳它的最大的数据成员(即一个union的存储空间至少要为其各个成员的数据类型中占字节数最大的一个成员的字节大小)。如下示例:

//测试2
union Token
{
    char cVal;      //char 类型, 1 个字节
    int nVal;       //int类型, 4个字节
    double dVal;    //double类型, 8个字节
};

union Token2
{
  short snVal;      //2个字节
  int nVal;         //4个字节
};

union Token3
{
  int nVal;         //4个字节
  float fVal;       //4个字节
  long lVal;        //4个字节
  char arr[20];     //20个字节
};

void TestUnion2()
{
    cout << "size of Token: " << sizeof(Token) << endl;
    cout << "size of Token2:" << sizeof(Token2) << endl;
    cout << "size of Token3:" << sizeof(Token3) << endl;
}

结果如下:

3.如果一个union结构中有多个相同类型的数据成员,则这些数据成员会有相同的值。union应该是根据成员占用的内存最大的数据类型的大小分配一段内存空间,不管你使用的是那个成员变量,内存空间地址和大小都相同。当然以上就是根据测试的例子个人进行的推断,在这个例子中char的空间首地址输出有问题,可能跟操作系统有关系,我用的是Ubuntu的Linux操作系统,如下示例:

//测试3
union Token4
{
    unsigned char cVal1;
    unsigned char cVal2;
    short int snVal;
    int nVal;
    long lVal;
    long long llVal;
    double dVal;
    double dVal2;
};

void PrintToken4(const Token4& t)
{
    cout << "char1:    " << t.cVal1 << "\t\t\t" << &t.cVal1 << endl;
    cout << "char2:    " << t.cVal2 << "\t\t\t" << &t.cVal2 << endl;
    cout << "short int:" << t.snVal << "\t\t\t" << &t.snVal << endl;
    cout << "int:      " << t.nVal << "\t\t" << &t.nVal << endl;
    cout << "long:     " << t.lVal << "\t\t" << &t.lVal << endl;
    cout << "long long:" << t.llVal << "\t" << &t.llVal << endl;
    cout << "double1:  " << t.dVal << "\t\t" << &t.dVal << endl;
    cout << "double2:  " << t.dVal2 << "\t\t" << &t.dVal2 << endl;
}

void TestUnion4()
{
    cout << "Print first:"<< endl;
    Token4 t;
    t.cVal1 = ‘A‘;
    PrintToken4(t);

    cout << endl << "Print second:"<< endl;
    t.nVal = 255;
    PrintToken4(t);
    cout << endl;

    cout << endl << "Print third:"<< endl;
    t.dVal = 10.2;
    PrintToken4(t);
}

结果如下:

4.C++的早期版本中(C++11标准之前),union不能含有定义了拷贝构造函数或拷贝控制成员的类类型成员。但在C++11标准之后取消了这一限制,可以含有类的成员,如string及自己定义的类。含有拷贝构造函数或拷贝控制成员的类类型成员的union比较复杂,可以去参考C++11标准的相关文档。

从Java到C++——union的用法,布布扣,bubuko.com

时间: 2024-12-29 05:02:08

从Java到C++——union的用法的相关文章

Java EE学习--Quartz基本用法

新浪博客完全不适合写技术类文章.本来是想找一个技术性的博客发发自己最近学的东西,发现博客园起源于咱江苏,一个非常质朴的网站,行,咱要养成好习惯,以后没事多总结总结经验吧.很多时候都在网上搜索别人的总结,我自己也总结些东西,或许多多少少能帮得上别人. 首先提到的是Quartz,一个开源的定期执行计划任务的框架.其实我内心好奇这个框架很久了,像那些能定时修改数据库数据,定时分配任务的功能一直觉得很神奇.心动不如行动,今天我就小小的学习了一下用法,力求言简意赅,大家都懂的我就不说了. 第一步:下载Qu

JAVA数组的定义及用法

数组是有序数据的集合,数组中的每一个元素具有同样的数组名和下标来唯一地确定数组中的元素. 1. 一维数组 1.1 一维数组的定义 type arrayName[]; type[] arrayName; 当中类型(type)能够为Java中随意的数据类型,包含简单类型组合类型,数组名arrayName为一个合法的标识符,[]指明该变量是一个数组类型变量. 另外一种形式对C++开发人员可能认为非常奇怪,只是对JAVA或C#这种开发语言来说,另外一种形式可能更直观,由于这里定义的仅仅是个变量而已,系统

Java HashSet和LinkedHashSet的用法

Java HashSet和LinkedHashSet的用法 类HashSet和LinkedHashSet都是接口Set的实现,两者都不能保存重复的数据.主要区别是HashSet不保证集合中元素的顺序,即不能保证迭代的顺序与插入的顺序一致. 而LinkedHashSet按照元素插入的顺序进行迭代,即迭代输出的顺序与插入的顺序保持一致. 以下是HastSet和LinkedHashSet的用法示例: [java] view plain copy import java.util.Collections

java中Object.equals()简单用法

/* equals()方法默认的比较两个对象的引用! */ class Child { int num; public Child(int x){ num = x; } //人文的抛出运行时异常的好处是:可以自定义错误信息! /*public boolean equals(Object o) throws ClassCastException{ if(!(o instanceof Child)) throw new ClassCastException("中文提示:类型错误"); Ch

java String.split()函数的用法分析

在java.lang包中有String.split()方法的原型是:public String[] split(String regex, int limit)split函数是用于使用特定的切割符(regex)来分隔字符串成一个字符串数组,函数返回是一个数组.在其中每个出现regex的位置都要进行分解.需要注意是有以下几点:(1)regex是可选项.字符串或正则表达式对象,它标识了分隔字符串时使用的是一个还是多个字符.如果忽略该选项,返回包含整个字符串的单一元素数组.(2)limit也是可选项.

union的用法

union的用法 union用来连接两个查询语句,把两个查询语句的查询结果合并起来,两个查询语句的查询字段个数必须一样,否则会出错,查询的字段可以不一样,类型也可以不一样,但是这样查询的意义不大,如果查询的字段不一样,最终的结果集以前者查询的字段为准.如果用union进行连接,碰到所有字段值一样的列,就会合并,去掉重复的行,如果用union all进行连接,则不会去掉重复的内容,所有的内容都被取出. mysql> (select goods_id,goods_name,cat_id from g

【转】JAVA网络编程之Socket用法

JAVA网络编程之Socket用法 分类: JAVA2012-08-24 15:56 710人阅读 评论(0) 收藏 举报 在客户/服务器通信模式中,客户端需要主动建立与服务器连接的Socket,服务器端收到客户端的连接请求,也会创建与客户端连接的Socket.Socket可以看做是通信连接两端的收发器,客户端和服务店都通过Socket来收发数据. 1.构造Socket public Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 public Socket(Str

Java包(Package)的详细用法(转)

Java包(Package)的详细用法 http://wenwen.soso.com/z/q229375145.htm 当一个大型程序交由数个不同的程序人员开发时,用到相同的类名是很有可能的,那么如果发生了这样的事件我们该怎么办那?,在我们java程序开发中为了避免上述事件,提供了一个包的概念(package),那么既然有了这样一种方法能避免上述事件,那么我们怎样使用package那?,使用方法很简单我们只需要在我们写的程序第一行使用package关键字来声明一个包就行了,例如我们来声明一个名为

Java中static、final用法小结(转)

一.final 1.final变量: 当你在类中定义变量时,在其前面加上final关键字,那便是说,这个变量一旦被初始化便不可改变,这里不可改变的意思对基本类型来说是其值不可变,而对于对象变量来说其引用不可再变.其初始化可以在两个地方,一是其定义处,也就是说在final变量定义时直接给其赋值,二是在构造函数中.这两个地方只能选其一,要么在定义时给值,要么在构造函数中给值,不能同时既在定义时给了值,又在构造函数中给另外的值. 当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的