ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

《C++深度解构02》类和对象(上)——定义规范、内存对齐与 this 指针全解

2026/8/18 13:09:23 拓冰建站 浏览量
《C++深度解构02》类和对象(上)——定义规范、内存对齐与 this 指针全解 文章目录一、 类的定义与基本结构1.1类定义格式class和struct1.2访问限定符1.3类域二、对象的实例化与内存模型2.1实例化的概念2.2对象大小的计算三、深入理解this指针3.1this指针的由来与作用3.2this指针的性质[ 本专栏所有配套代码已同步至 GitHub点击直达]一、 类的定义与基本结构1.1类定义格式class和struct类的定义与C语言中的结构体定义格式类似并且C中兼容C所以用struct也可以创建类class类名{成员变量 成员函数};C中将变量和函数封装放到一起构成了类成员变量成员函数小tips为了区分普通变量和成员变量我们一般在成员变量前加一个_来区分classA{//成员函数public:voidInit(intyear,intmonth,intday){_yearyear;_monthmonth;_dayday;}voidPrint(){cout_year_month_day;}//成员变量private:int_year;int_month;int_day;};习惯上我们将成员函数放在上成员变量放在下创建注意创建的类相当于C语言中的函数声明没有对象这个实体所以也没有开辟空间后续创建了实体——对象才会开辟空间。struct也可以创建类但是和class相比略有差距C中struct无需再通过typedef来重命名无需再带上struct直接使用结构体名就可以代表类型C兼容C所以即使写typedef也正确不给定访问限定情况class定义的类访问限定权限默认是private私有struct定义的类的访问限定权限默认public公有1.2访问限定符public公有private私有protected保护在目前阶段private和protected的功能一致就是在类外无权限访问但是在类内可以随意访问public则是在类内外都可以任意访问。通常情况我们只对外提供函数接口所以成员变量一般都是private或者protected成员函数为public1.3类域在C入门基础中我们了解到域分为函数局部域全局域命名空间域类域四种类的所有成员都在类域中域外需要访问时要使用:: 域限定作用符在类中函数声明和定义也可以分离但是分离后在类外需要 :: 来访问structA{public://函数声明voidInit(intyear,intmonth,intday);voidPrint(){cout_year_month_day;}private:int_year;int_month;int_day;};//类外访问域限定作用符访问voidA::Init(intyear,intmonth,intday){_yearyear;_monthmonth;_dayday;}二、对象的实例化与内存模型2.1实例化的概念定义形象比喻类像是建造房子的图纸对象就是按照图纸建造的房子一张图纸可以建造许多房子类是对象的模板而对象是类的实例化对象的创建和使用方式与结构体的使用方式完全一致直接使用类型名创造对象需要访问对象内的成员则使用成员访问运算符访问. 和 -指针类型classA{public://成员函数voidInit(intyear,intmonth,intday){_yearyear;_monthmonth;_dayday;}voidPrint(){cout_year/_month/_dayendl;}private://成员变量int_year;int_month;int_day;};intmain(){A a;a.Init(100,20,30);a.Print();return0;}类的创建并不会为其分配内存空间只有实例化对象时才会有内存空间的分配2.2对象大小的计算我们说结构体的使用方法与类和对象的使用方法一致那么存储对象的方式是不是也是异曲同工之妙呢想像一个场景我们利用类实例化了100个对象每个对象都是独立的数据空间成员变量有所不同所以这100个对象中的每一个成员变量都存储在自己的对象中但是每个对象中的成员函数都是相同的而且函数被编译后是一段指令对象内无法存储所以如果每个成员函数都分别存在自己的对象中那么100个对象的内存大小是相当大的函数的执行逻辑都是相同的对象中的成员函数不存在对象内而是只保存一份代码指令保存在“ 代码段 ”中内存对齐规则classHy{public:voidprint(){coutprint()endl;}private:char_a;int_b;};char类型值从地址偏移量为0的位置开始存放char的大小为1小于vs默认对齐数故占用1个字节位置int类型值对齐数为4对齐到最近的整数倍即从偏移量为4的的位置开始存放中间三个字节依次填充然后他的大小为4字节整体加下来为8字节是最大对齐数4的倍数所以这个对象的大小为8字节特殊情况classHy{private:voidprint(){coutprint()endl;}};没有成员变量的对象大小为1这个1纯粹是为了证明对象的存在。三、深入理解this指针3.1this指针的由来与作用同一个类实例化出的对象中的成员函数是同一个只会存储一份调用函数时他们是如何获取不同对象中的成员变量呢classData{public:voidInit(intyear,intmonth,intday){_yearyear;_monthmonth;_dayday;}voidprint(){cout_year/_month/_dayendl;}private:int_year;int_month;int_day;};两次调用成员函数print对于编译器来说这是相同的一段指令那么他是如何获得成员变量数据的呢在编译链接阶段编译器会自动为成员函数形参部分提供ClassName* const this指针这里为隐士传递相当于在调用时自动传入了对象的地址从而在函数的形参中接收到了函数的地址进而隐式解引用获得成员变量数据。3.2this指针的性质voidInit(/* Data* this */intyear,intmonth,intday){this-_yearyear;this-_monthmonth;this-_dayday;}存储在栈区作为函数形参传入或者特定寄存器中如ECX不能显式写在参数和形参中但是可以写在函数定义内下期预告类和对象中—类的六大默认构造函数