编码运行环境:VS2017+Win32+Debug,Win32表示生成32bits的应用程序。

文章目录

  • 1.struct
  • 2.union
    • 2.1 基本性质
    • 2.2 高级特性
  • 参考文献

结构体(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++中使用结构体需要注意以下几点:

(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.1 基本性质

通过如下程序考察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;
}

程序运行结果:

4
-51 -51 -51 -51
-842150451
A
65 -51 -51 -51
-842150591

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

2.2 高级特性

观察如下程序。

#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;
}

程序运行结果:

A
8.9
65
U
3

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

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

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

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

(4)union 允许其他类的对象成为自己的数据成员,但是要求该类对象所属类不能定义 constructor,copy constructor,destructor,assignment operator,virtual function 中的任意一个。因为:
(a)union 数据成员共享内存,union构造函数在执行的时候,不能调用数据成员为类对象的构造函数,否则就改变了其他数据成员的值。
(b)同样,union 的对象成员的析构函数也不能被调用,因为其他数据成员的值对于对象成员而言可能毫无意义。
(c)union 的对象成员的赋值应该维持其原始语义,不建议进行赋值运算符的重载,因为赋值运算符重载一般用于“深拷贝”等场合,而在对象空间与其它变量共享的情况下,“深拷贝”引入的内存资源,指向内存资源的指针往往会被其它共用体数据成员修改,导致内存资源无法寻址,造成内存泄漏。此外,因为 union 的对象成员没有自定义的析构函数,也会导致内存泄漏。
(d)拥有虚函数的类对象,虚函数表指针可能会在共用体对象初始化时被覆盖,导致无法寻址虚函数表,所以也不能拥有虚函数。

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

(6)匿名共用体(Anonymous Union),也就是给出一个不带名称的共用体的申明后,并不定义任何该union的变量,而是直接以分号结尾。严格来说,匿名共用体并不是一种数据结构,因为它不能用来定义共用体对象,它只是指明若干个变量共享一片内存单元。在上例中,对变量 p 的修改实际上修改了变量 q。可以看出,尽管匿名共用体中的变量被定义在同一个共用体中,他们与同一个程序块的任何其他局部变量具有相同的作用域级别。这意味着匿名共用体内的成员的名称不能与同一个作用域内的其它标识符相冲突。另外,对匿名共用体还存在如下限制:
(a)匿名共用体不允许有成员函数;
(b)匿名共用体也不能包含私有或者保护成员;
(c)全局匿名共用体中的成员必须是全局或静态变量。


参考文献

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

C++ struct 与 union相关推荐

  1. 数据类型:Struct 和 Union区别

    参考:Struct 和 Union区别_firefly_2002的专栏-CSDN博客_union和struct的区别 Struct 和 Union有下列区别: 1.在存储多个成员信息时,编译器会自动给 ...

  2. C++报错解决:error: ‘int’ is not a class, struct, or union type typedef typename _Sequence::value_

    我在使用C++的时候,遇到了如下报错: -> % g++ test.cpp In file included from /usr/include/c++/7/queue:64:0,from te ...

  3. c语言struct_Introduction to CSAPP(十七):复杂数据组织与C语言的 struct与union

    如果说数组是同一种类型的数据的连续排列的数据组织形式,那么对于不同类型的数据来说,他们被有机组织起来的方式有两种,分别是struct和union. Struct C语言的 struct 创建一种数据类 ...

  4. 转 Struct 和 Union区别 以及 对内存对齐方式的说明

    转载地址:http://blog.csdn.net/firefly_2002/article/details/7954458 一.Struct 和 Union有下列区别: 1.在存储多个成员信息时,编 ...

  5. [C/C++基础知识] 面试再谈struct和union大小问题

    最近找工作参加了很多笔试,其中考察结构体和联合体的大小问题是经常出现的一个问题.虽然题目简单而且分值比较低,但是还是想再给大家回顾下这些C和C++的基础知识.希望文章对你有所帮助~         P ...

  6. struct and union

    [url]http://hi.baidu.com/tweigh/blog/item/5303d2ef6e2720eace1b3e9d.html[/url] 1. struct的巨大作用 面对一个人的大 ...

  7. C++ Struct和Union区别

    C++ Struct和Union区别 Struct和Union区别 在存储多个成员信息时,编译器会自动给struct每个成员分配存储空间,struct可以存储多个成员信息,而Union每个成员会用同一 ...

  8. X86汇编中的结构体STRUCT和UNION

    X86汇编中的结构体STRUCT和UNION 结构的定义 ; 定义名为Person的结构体 Person STRUCTidNum byte "000000"lastName byt ...

  9. C语言里struct和union的区别

    struct和union是C语言的两种数据结构,这两种都是常用的复合结构. 区别: (1) 联合体:所有成员共用一块地址空间,也就是说联合体只放了一个被选中的成员: 结构体:所有的成员的内存占用是累加 ...

最新文章

  1. html字符实体和实体名称 lt;
  2. RSS FEED的应用
  3. 哈希值+非对称加密+网络+数字签名,你真的知道怎么给游戏充钱吗
  4. app上传遇到的一些问题
  5. 处理 TXT 文本技巧
  6. 肖维勒准则matlab_肖维勒准则.PPT
  7. 阿里云邮件推送使用方法
  8. stm32驱动TFTLCD液晶屏显示图片+汉字(快速上手,只教怎么用,不讲原理!)
  9. PCL中点云配准精通级实例解析
  10. 关联规则分析(频繁项集查找方法为apriori方法的Fk-1*Fk-1)
  11. 手机梦幻模拟战更新服务器正在维护,梦幻模拟战手游9月13日更新了什么 梦幻模拟战更新维护公告...
  12. bug日志-win10任务栏卡死、无法加载
  13. 定时器控制交通指示灯
  14. wpt eclipse 使用指南
  15. 【JZOJ 100029】【NOIP2017提高A组模拟7.8】陪审团 (贪心+排序)
  16. Multiplayer Moo
  17. 用二进制数字串生成二维码图片
  18. 消除“你可能是盗版软件受害者”的提示(XP蓝星)
  19. PyTorch深度学习实践 Lecture09 Softmax 分类器
  20. APISpace 月出月落和月相API接口 免费好用

热门文章

  1. 研究员拒绝提前通知,Zoho 匆忙修复一个严重的 0day
  2. 能让程序员瞬间崩溃的五个瞬间,共鸣的同学请举手!
  3. SQLMETAL :Linq对象生成
  4. xamarin.android searchview的一些用法
  5. 建立密钥,远程登录LINUX----ssh-keygen
  6. JFinal 调用 oracle 存储过程的 步骤
  7. 架设WIN32汇编程序的开发环境
  8. 2010-03-23 杂七杂八
  9. 国内Linux认证类型详解
  10. 那英、那狗、那年、那事