C++面向对象基础——数据语义学

PS:这节课感觉没有太多东西

歧义的纠正

在 C 里面,局部变量和全局变量是可以同名的,但是局部变量会屏蔽全局变量。同样的,在类内也是这样,它会尽量在作用域范围较小的地方找到定义。即使我函数只在类内申明,类外定义,依然是会优先找到类内的定义的,因为成员函数不管在哪里定义,它的作用域都是在类内。

但是呢,跟之前的类一样,重写的方法具有覆盖继承方法的特性,只是因为它优先在本作用域找而已,并不是说就没了,我们想调用依然可以调用,我们在调用成员方法之前使用 FatherClass:: 限定作用域可以去调用父类的成员方法和成员变量。同样,我们如果类内和类外都定义了同名的变量,我们可以加上 :: 标定我们方法全局作用域的变量,这样就可以解决变量屏蔽的问题了。

预处理设置数据对对齐

#pragma pack 的主要作用就是改变编译器的内存对齐方式,这个指令在网络报文的处理中有着重要的作用,#pragma pack(n)是他最基本的用法,其作用是改变编译器的对齐方式, 不使用这条指令的情况下,编译器默认采取#pragma pack(8)也就是8字节的默认对齐方式,n值可以取(124816) 中任意一值。

#pragma pack(show):

#pragma pack(show)显示当前内存对齐的字节数。也就是packing aligment。我们常说编译器默认8字节对齐我们怎么知道的呢,用这个预处理命令可以让编译器输出这个值。

#pragma pack(push [, identifier] [, n])

单纯使用#pragma pack(push)会将当前的对齐字节数压入栈顶,并设置这个值为新的对齐字节数, 就是说不会改变这个值。

而使用#pragma pack(push, n) 会将当前的对齐字节数压入栈顶,并设置n为新的对齐字节数。

再就是这个#pragma pack(push, identifier [, n])会在上面的操作基础上为这个对齐字节数附上一个标识符, 这里注意这个标识符只能以($_字母)开始, 标识符中可以有($_字母数字),并且标识符不能是关键字(push, pop可以作为标识符)。

#pragma pack(pop [, identifier] [, n])

同样单纯使用#pragma pack(pop)会弹出栈顶对齐字节数,并设置其为新的内存对齐字节数。

使用#pragma pack(pop, n)情况就不同了, 他会弹出栈顶并直接丢弃,设置n为其新的内存对齐字节数。

#pragma pack(pop, identifier [, n])较为复杂,编译器执行这条执行时会从栈顶向下顺序查找匹配的identifier,找到identifier相同的这个数之后将从栈顶到identifier,包括找到identifier全部pop弹出, 若没有找到则不进行任何操作。