C++的struct和union

编码运行环境:VS2012+Win32+Debug

Win32既表示运行平台是Windows 32bits操作系统,又表示生成32bits的应用程序。



结构体(struct)与联合体(union)是C语言中就已经存在的数据类型。C++语言对他们进行了扩充,最大的变化是允许在结构和联合体中定义成员函数。下面将通过实例讲解二者的特性和用法。

1.struct

以下是一个使用了结构的C++程序。

#include <iostream>
using namespace std;

struct Room{
        int floor;
        int No;
};

struct Student{
    int age;
    int score;
    Student(int a,int s){
        age=a;
        score=s;
    }
};

int main(int argc,char* argv[])
{

    Room r[3]={{1,101},{2,201},{3,301}};
    Student s(18,89);
    cout<<"the room are:";
    cout<<r[0].floor<<"-"<<r[0].No<<" ";
    cout<<r[1].floor<<"-"<<r[1].No<<" ";
    cout<<r[2].floor<<"-"<<r[2].No<<endl;
    cout<<"the student‘s age:"<<s.age<<" score:"<<s.score<<endl;
    getchar();
}

程序运行结果:

the room are:1-101 2-201 3-301

the student’s age:18 score:89

阅读以上程序,在C++中使用结构体(struct)要注意一下几点:

(1)C++中,结构体是一种真正的数据类型,在利用结构定义变量时,不需要像在C中带上struct关键字,或先使用typedef struct structname structalias的方式进行申明。

(2)C++对C中的struct进行了扩充,允许在struct中定义成员函数。Struct中的成员变量和长远函数也有访问权限。在class中,默认的访问权限是private,而在struct中默认访问权限是public,这是结构和类的唯一区别。Struct成员的默认访问权限设为public是C++保持与C语言兼容而采取的一项策略。

(3)如果struct中没有显示定义任何构造函数,那么结构变量可以像在C语言中那样用花括号顺序指明数据成员的值来进行初始化。但是一旦显示定义了任何一个构造函数,就不能用这种方式初始化了。如果在class中只有若干public型的数据成员,而没有显示定义任何构造函数,也可以使用花括号进行初始化。

(4)用sizeof运算符计算结构的大小时,要考虑结构体内部变量的对齐问题。

请牢记,在struct中默认访问权限是public,这是结构和类的唯一区别。

2.union

联合(union)是一种特殊的类,很少用但很有用。它是从C语言章继承而来的,其基本予以没有发生什么变化,只是具有了类的一些特性(允许定义成员函数)。与结构不同的是,联合中的数据成员共享了一段内存,以达到节省空间的目的。

2.1union的基本性质

通过如下程序考察union变量的占用空间,成员赋值时的相互影响。

#include <iostream>
using namespace std;
union testunion{
    char c;
    int i;
};
int main(int argc,char* argv[])
{
    cout<<sizeof(testunion)<<endl;
    testunion* pt=new testunion;
    char* p=reinterpret_cast<char*>(pt);
    for(int i=0;i<sizeof(*pt);i++)
        cout<<int(p[i])<<" ";
    cout<<endl;
    cout<<pt->i<<endl;
    pt->c=‘A‘;
    cout<<pt->c<<endl;
    for(int i=0;i<sizeof(*pt);i++)
        cout<<int(p[i])<<" ";
    cout<<endl;
    cout<<pt->i<<endl;
    delete pt;

    getchar();
}

程序运行结果:

4

-51 -51 -51 -51

-842150451

A

65 -51 -51 -51

-842150591

可以看出,union testunion变量的体积是4,它是由两个数据成员中体积较大的一个(int)类型来决定的。对其中一个数据成员的修改,一定会同时改变所有其他数据成员的值。不过对体积较小的数据成员的修改,只会影响到该成员应该占用的那些字节,对超出部分(高位字节)没有什么影响。

2.2union的高级特性

观察如下程序。

#include <iostream>
using namespace std;
struct Student{
    int age;
    int score;
    Student(int a,int s){
        age=a;
        score=s;
    }
};

union testunion{
    char c;
    int i;
};

class someClass{
    int num;
public:
    void show(){
        cout<<num<<endl;
    }
};

union A{
    char c;
    int i;
    double d;
    someClass s;
};

union B{
    char c;
    int i;
    double d;
    B(){
        d=8.9;
    }
};

union{
    char c;
    int i;
    double d;
    void show(){
        cout<<c<<endl;
    }
}u={‘U‘};

int main(int argc,char* argv[])
{
    A a={‘A‘};
    B b;
    cout<<a.c<<endl;
    cout<<b.d<<endl;
    a.s.show();
    u.show();

    union{
        int p;
        int q;
    };

    p=3;
    cout<<q<<endl;
    getchar();
}

程序运行结果:

A

8.9

65

U

3

阅读以上程序,需要注意以下几点:

(1)union可以指定成员的访问权限,默认情况下,与struct具有一样的权限(public)。

(2)union也可以定义成员函数,包括构造函数和析构函数。与struct不同的是,它不能作为基类被继承。

(3)union不能拥有静态数据成员或引用成员,因为静态数据成员实际上并不是联合体的数据成员,它无法和联合体的其它数据成员共享空间。对于引用变量,引用本质上是一个指着常量,它的值一旦初始化就不允许修改。如果联合体有引用成员,那么联合体对象一创建初始化后就无法修改,只能作为一个普通的引用使用,这就失去了联合体存在的意义。

(4)union允许其他类的对象成为自己的数据成员,但是要求该类对象所属类不能定义constructor,copy constructor,destructor,copy assignment operator, virtual function中的任意一个。如此设计时局域共享内存的考虑。

(5)如果union类型旨在定义该类的同时使用一次,以后不再使用了,那么也可以不给出union的名称。如上例中变量u就是这种情况,这中情况下,无法为该union定义构造函数。

(6)匿名联合(anonymous union),也就是给出一个不带名称的联合体的申明后,并不定义任何该union的变量,而是直接以分号结尾。严格来说,匿名联合并不是一种数据结构,因为它不能用来定义变量,它只是指明若干个变量共享一片内存单元。在上例中,对变量p的修改实际上就是修改了变量q。可以看出,尽管匿名联合中的变量,尽管被定义在一个联合申明中,他们与同一个程序块的任何其他局部变量具有相同的作用域级别。这意味着匿名联合内的成员的名称不能与同一个作用域内的其它标识符相冲突。

另外,对匿名联合还存在如下限制:

- 匿名联合不允许有成员函数;

- 匿名联合也不能包含私有或者保护成员;

- 全局匿名联合中的成员必须是全局或静态变量。


参考文献

[1]C++高级进阶教程.陈刚.武汉大学出版社

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-24 11:19:22

C++的struct和union的相关文章

struct和union的区别

当初学习C语言时并没有特别注意 union 的用法,也不知道与 struc t相比有何不同.经过网上的一番搜索,现在总算是恍然大悟,所以就小结一下.如有错误之处,敬请指正.( struct 和 union 的结构定义形式没有多大差别,只要不是初学者,相信大家不会在这方面存在什么问题.) struct 简单来说就是一些相互关联的元素的集合,说是集合,其实它们在内存中的存放是有先后顺序的,并且每个元素都有自己的内存空间.那么按照什么顺序存放的呢?其实就是按你声明的变量顺序来存放的,下面先看一个例子:

2015-10-20 关于struct和union

1.结构体: 1.1.思考题:空结构体占用多大内存空间? ANS:不同的编译器,这个结果是不定的.在GCC下,空结构体占用0个字节的空间.在G++编译器下,空结构体占用1个字节的空间. 1.2.一个新的概念----柔性数组 柔性数组:数组大小待定的数组. C语言中结构体的最后一个元素可以为一个大小未知的数组.于是可以利用该特性来产生柔性数组: struct _soft_array { int len; int array[]; }; 此处有一个问题是需要注意的:sizeof(_soft_arra

struct与union

1. union的长度 union { int k; int p[4]; double q; }data; sizeof(data)=20; //结构体中最大的数据长度 2.struct的长度 struct { int k; double q; }data; sizeof(data)=16; //结构体中最大的数据长度的倍数(默认情况,如果设置了不同的内存对齐另当别论): //如果以1字节.4字节对齐的话,sizeof(data)=12: 3.struct与union的联合使用 void str

&lt;转&gt; Struct 和 Union区别 以及 对内存对齐方式的说明

转载地址:http://blog.csdn.net/firefly_2002/article/details/7954458 一.Struct 和 Union有下列区别: 1.在存储多个成员信息时,编译器会自动给struct第个成员分配存储空间,struct 可以存储多个成员信息,而Union每个成员会用同一个存储空间,只能存储最后一个成员的信息. 2.都是由多个不同的数据类型成员组成,但在任何同一时刻,Union只存放了一个被先选中的成员,而结构体的所有成员都存在. 3.对于Union的不同成

【转】C/C++ struct/class/union内存对齐

原文链接:http://www.cnblogs.com/Miranda-lym/p/5197805.html struct/class/union内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括stru

C/C++ struct/class/union内存对齐

struct/class/union内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括struct/class/uinon. 2).结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部"

关于C中struct和union长度的详解

这几天看<代码大全>中的第十三章---不常见的数据类型,里面讲解到了C语言中的struct以及对指针的解释,联想到以前看过相关的关于C语言中stuct长度的文章,只是现在有些淡忘了,因此今天把保存的资料重新拿出来温习一遍,同时写下这篇文章,对以前相关资料总结的同时顺便梳理一下已有的知识. 一.基本数据类型在内存中的长度 关于基本的数据类型,在不同的机器上占据的长度不一样.为了能够对数据的组合类型(这里只包括了struct和union)能够有一个清晰地认识,这里首先对基本的数据类型在不同位数(3

struct与union字节大小的终极解释

1.字节对齐的细节和编译器实现相关,但一般而言,如在windows下,就VC而言,满足一下三个准则:1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除:2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding): 即:在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量:sizeof(类型)或其倍数3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译

C之 struct 和 union(十)

在 C 语言中我们经常会使用到 struct 和 union,那么它们两个各自有何特点呢?今天我们就一探究竟. 我们先来介绍下 struct .它可以看做是变量的集合,那么一个空的结构体占多大内存呢?这是一个有趣的问题,按照理论分析,它应该是0.但是按照 C 语言的设计思想来说,不可能存在空结构体的,定义一个空结构体没意义啊,所以应该报错的.下来我们就分别在 gcc 和 BCC 编译器上实验下.由于代码比较简单,就不贴代码了,我们直接来结果.图一为在 gcc 编译器下编译的,图二为在 BCC 编

struct和Union的内存分配

eg: struct node{ char c ; int x ; }; 在你定义一个这个的node后, 系统给它分配的内存不是简单的就是sizeof(char)+sizeof(int)= 5 :  而是采用内存对齐的方式 . 首先在计算机中 , 会有一个默认的参数 , 即对齐膜数 , 一般默认为8字节 , 但可以通过在程序中添加如下命令来改变其值 #pragma pack(n) ; 在知道对齐模数后, 就可以开始说对齐规则了 1:在系统给其分配内存时 , 是安照你定义的先后的原则 , 比如说上