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

微信公众号: 星点课堂

新浪微博:女儿叫老白

网易云课堂:女儿叫老白

网易云课堂免费课程:《C++跨平台开发中的编译错误》

---------------------------------------------------------------------------

       如果您学习使用过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默认是private继承

3. struct可以取消对齐,struct则无法取消对齐。

如果您有有不同意见,欢迎补充。

猜你喜欢

转载自blog.csdn.net/baizy77/article/details/82592727
今日推荐