前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ struct与union

C++ struct与union

作者头像
恋喵大鲤鱼
发布2018-08-03 17:16:01
5950
发布2018-08-03 17:16:01
举报
文章被收录于专栏:C/C++基础C/C++基础

编码运行环境:VS2012+Win32+Debug Win32既表示运行平台是Windows 32bits操作系统,又表示生成32bits的应用程序。


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

1.struct

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

代码语言:javascript
复制
#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();
}

程序运行结果:

代码语言:javascript
复制
the room are:1-101 2-201 3-301
the student's age:18 score:89

阅读以上程序,在C++中使用结构体需要注意以下几点: (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运算符计算结构的大小时,要考虑结构体内部变量的对齐问题。

2.union

共用体(union)是一种特殊的类,从C语言章继承而来,其基本语义没有发生什么变化,只是具有了类的一些特性(允许定义成员函数)。在实际的编程实践中,使用频率没有struct高。与struct相比,最显著的区别是union的数据成员共享同一段内存,以达到节省空间的目的。

2.1union的基本性质

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

代码语言:javascript
复制
#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;
}

程序运行结果:

代码语言:javascript
复制
4
-51 -51 -51 -51
-842150451
A
65 -51 -51 -51
-842150591

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

2.2union的高级特性

观察如下程序。

代码语言:javascript
复制
#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;
}

程序运行结果:

代码语言:javascript
复制
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。可以看出,尽管匿名共用中的变量被定义在同一个共用体中,他们与同一个程序块的任何其他局部变量具有相同的作用域级别。这意味着匿名共用内的成员的名称不能与同一个作用域内的其它标识符相冲突。另外,对匿名共用还存在如下限制: (6.1)匿名共用不允许有成员函数; (6.2)匿名共用也不能包含私有或者保护成员; (6.3)全局匿名共用中的成员必须是全局或静态变量。


参考文献

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015年08月17日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.struct
  • 2.union
    • 2.1union的基本性质
      • 2.2union的高级特性
      • 参考文献
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档