找回密码
 立即注册
收起左侧

C++老鸟日记018 class与struct有啥不一样

4
回复
5440
查看
[复制链接]
累计签到:41 天
连续签到:1 天
来源: 原创 2018-9-10 17:10:29 显示全部楼层 |阅读模式

马上注册,查看详细内容!注册请先查看:注册须知

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 baizy77 于 2018-10-1 20:50 编辑

版权声明
---------------------------------------------------------------------------------------------------------------------
该文章原创于Qter开源社区(www.qter.org
作者: 女儿叫老白 (白振勇)
转载请注明出处!
---------------------------------------------------------------------------------------------------------------------
本套课程属于:《C++跨平台开发干货》系列课程。
-----------------------------------------------------------------------------

引言
-----------------------------------------------------------------------------
       在C++中,struct用的好像越来越少了,因为由于需要进行接口封装,用class基本上完全取代了struct,那么 class与struct到底有啥区别呢,今天我们就来看一下。

正文
---------------------------------------------------------------------------
       如果您学习使用过C++语言,那么您可能知道,class与struct的第一个不同:
       class的成员默认是private而struct正相反,其成员默认是public的。
       当然,他们都允许拥有成员函数。
       除此之外,class与struct还有啥不一样吗?
当然有啦。class默认是private继承而struct默认是public继承。在进行跨平台编程的时候,我们会碰到对齐问题,这里的对齐指的是内存地址对齐。我们先来普及一下内存对齐的知识。
计算机中内存的地址都是按照字节划分的,因此从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,
但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,
这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。
有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误。那么在这种架构下编程必须保证字节对齐。其他平台可能没有这种情况,
但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。
比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,
而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
       这就是内存对齐的知识。从上述描述可以得知,如果不进行配置,为了提高访问效率有些编译器会对变量的内存地址进行优化,比如编译器会把int型(假设为32位系统)变量放在4的倍数的内存地址上,这样编译器在1个cpu周期就可以获取该变量的值。但是这就会浪费内存并且在进行跨平台编程时带来麻烦。比如在不同的机型(或操作系统)上进行通信时,通信双方的对齐方式必须是相同的,否则就会出现地址偏差导致获取的数据有误甚至导致内存访问越界。为了处理这种问题,我们可以采用取消对齐的方法,或者将内存向1的倍数对齐。因为任何地址都是1的倍数,因此就相当于取消对齐了。struct可以取消对齐,而class不能取消对齐。在有些编译器版本中,如果将一个类的成员变量地址(或引用)传递给一个函数,可能导致编译器告警,和运行时异常。      
取消对齐的方法比较复杂,我们这里只简单给大家介绍一下gcc编译器的取消对齐的方法:
       gcc编译器取消对齐的指令:
__attribute__((packed))
该指令需要在结构体结尾处声明,比如:
struct str_struct{
       Juint8    a;
       Juint8    b;
       Juint8    c;
       Juint16   d;
} __attribute__((packed));
关于对齐的更多内容,欢迎关注后续课程。
------------------------------总结 ----------------------------
1. class的成员默认是private,struct的成员默认是public
2. class默认是private继承,struct默认是public继承
3. struct可以取消对齐,class则无法取消对齐。
如果您有不同意见,欢迎补充。

回复

使用道具 举报

累计签到:882 天
连续签到:3 天
2018-9-11 09:10:07 显示全部楼层
总结有笔误。。。。。。
回复 支持 反对

使用道具 举报

累计签到:50 天
连续签到:1 天
2018-9-11 09:58:39 显示全部楼层
关于对齐的更多内容,欢迎关注后续课程。
------------------------------总结 ----------------------------
1. class的成员默认是private,struct的成员默认是public
2. class默认是private继承,struct默认是private继承
3. struct可以取消对齐,struct则无法取消对齐。
如果您有有不同意见,欢迎补充。


老师写得匆忙 。
回复 支持 反对

使用道具 举报

累计签到:41 天
连续签到:1 天
2018-9-11 11:05:20 显示全部楼层
tan 发表于 2018-9-11 09:58
关于对齐的更多内容,欢迎关注后续课程。
------------------------------总结 -------------------------- ...

确实匆忙了,没有仔细检查,谢谢。
回复 支持 反对

使用道具 举报

累计签到:41 天
连续签到:1 天
2018-9-11 11:06:47 显示全部楼层
一叶知秋 发表于 2018-9-11 09:10
总结有笔误。。。。。。

确实写得匆忙了,没有认真检查,感谢您的提醒。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了