各位好友,欢迎来到本期博文 !本期,继续推进上一期内容 !
-------> 结构体
下面重点讲解, 如何计算一个结构体的大小 !
现定义一个结构体,如下 :>
1. 内存对齐规则
(1)第一个成员在于结构体偏移量为 0 的地址;
(2)其他成员变量要对齐到某一个数字(对齐数)的整数倍的地址处;
注意:> 对齐数 = 编译器默认的一个对齐数 与 该成员字节大小的较小值; VS 默认对齐数的大小为 8
(3)结构体总大小为:最大对齐数(所有变量类型最大值与默认对齐参数取最小值)的整数倍;
(4)如果 嵌套了结构体,嵌套的结构体对齐到自己最大对齐数默认的整数倍,结构体的整体大小就是所有最大对齐数(包含嵌套的结构体)整数倍 !
2. 计算结构体大小(重点)
为了方便好友们,有更好的观感,与更好地理解 !以下分析,均是采用彩色图示,请观察:>
以上就是,结构体大小的相关计算了 !
其实,只要学会了方法,无论 怎样变化 变量类型,以及 成员个数,总能应付自如 !😊
-------> this 指针
各位好友,先来看看下面的代码实现 !从而开启“this”指针战斗,这需要有相对应的切入点 ! 如下所示:
#include <iostream>
using std :: cout;
using std :: endl;
struct Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << " - " << _month << " - " << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1, d2;
d1.Init(2023, 05, 01);
d2.Init(,2023, 05, 02);
d1.Print();
d2.Print();
return 0;
}
为了方便好友们,有更好的观感体验,与更好的理解,现附上有彩色的代码图样 :>
请观察上述代码:为什么,打印函数都没有入参数,最终却 打印出了正确的结果!以及,打印函数是如何区分不同的对象 d1 与 d2 的?其实,这是 “ this ”指针 运用 !
C++ 中通过引入 this 指针,使得 C++ 编译器给每个 “非静态的成员函数” 增加了一个隐藏的指针参数,让该指针指向当前对象(即函数调用的时候访问的对象)
在函数体 所有 "成员变量"的操作,都是通过该指针去访问的。 如此,用户不需要传递实参,编译器自动完成 !
也是说,由以前的手动挡变换成了自动挡 !这也是 C++ 优化处理函数的表现之一 !更高效,更加惹人喜爱 !😊
-----> this 指针是否可以显示 --->可以部分显示 -->如下 :>
如果 在参数部分展现出来 是否可行呢 ?
----->如下 :>
请注意观察,上述红色标注点 !此时,一定要注意 const 位置,表明 const 修饰指针本身,this 指针指向的内容可以被修改 !现理解 上述参数部分:>本类名下的 this 指针类型 。一定别忘了,要加一个 const 进行修饰 !
因为,this 指针是一个关键字,无法被修改 !
由 上述图示可知, this 指针不能在形参部分显示出来,但可以在函数体内部显示出来 !
上述,“ this ” 指针实现日期显示,已经完成 !下面讲述 “ this ” 指针特性 !
------->“ this ” 指针特性
(1)this 指针类型:类的类型* const, 即成员变量函数中,不能给 this 指针赋值 ;
(2)只能在 “成员函数” 内部实现;
(3)this 指针,本质是 “成员函数”的形参。
当对象调用成员函数时,将对象地址作为实参传递给 this 形参。总之,对象中不存储 this 指针 ;
(4)this 指针是 “ 成员函数 ” 第一个隐含的指针形参。一般情况下,由编译器 通过 ecx 寄存器自动传递,不需要 用户传递 。
那么,上述结论中,该如何理解 特性 (4)呢 ?显然要用到反汇编,看底层逻辑,如下所示 :>
在了解反汇编之前,首先 会有疑问, this 指针,存储在哪里 ?
以上部分,讲解 this 指针的错误用法,得知 不能在参数部分进行显示,一个函数的参数显然在 栈区 !
因此, this 指针是跟普通参数一样存在于函数调用的栈区里面 !上述反汇编中出现的 “push” 就是 压栈 之意 !
下面,请观察反汇编 !VS 内部对 this 指针进行优化,对象的地址放在 ecx ,而寄存器 ecx 存储 this 指针的值
接下来,测试 this 指针 是否可以为 空,如下 :>
此时程序正常运行
----->d1 调用Print,不会发生解引用,因为Print的地址不在对象中, d1 作为实参传递给 this 指针
同时, this 指针是空的,但是函数内部没有对指针进行解引用 !显然是可行的 !
此时程序运行崩溃
----->d1 调用 Print() 函数,不会发生解引用,因为 Print() 函数地址不在对象中。 d1会作为实参传递给 this指针
同时, this 指针为空,但函数内部访问 _a, 本质上是 this -> _a 显然程序出现了 Bug !
上述,this 指针为空的时候,不光不能传递,还不能显示;
注意,A 是类名,不存在 空间; 声明类之后, 创建的对象,才会具有空间 !这在前期博文有讲解 !不清楚的好友可以自行查看之前的博文 !😊
其实, this 指针的运用,隐藏 是很新颖的!之前 用 C++ 实现栈区,发现了好多函数同样没有传参,但却能运行
至于原因,想必好友们,已经得知了 !很香的 C++ 栈区实现,同样有隐藏版的指针 !😊😊
以上就是本期博文,新的玩法, this 指针 !隐藏 或成为开发项目中 必不可或缺的一点 !
至此,本期博文,已完结!希望本期博文,为好友们带来了 新的体验 !下一期,仍然是 继续推进 大类 大对象
敬请期待 !感谢你的阅读 ! 希望 C++ 领域能使你绽放光彩 !😊😊