> 文档中心 > Let’s Make C++ Great Again——类的实例化与大小及this指针

Let’s Make C++ Great Again——类的实例化与大小及this指针

目录

  • 类的实例化
  • 计算类的大小
  • this指针
    • 引入
    • 特性

类的实例化

用类类型创建对象的过程,称为类的实例化

  1. 类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它
  2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
  3. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

计算类的大小

计算类的大小,我们可能想到是不是和C语言中计算struct的大小方法是一样的。

但是,问题是class中包括了struct中成员函数

在这里插入图片描述

我们发现并没有计算函数的大小,实际上我也还从听说过函数有大小。

实际情况如下:
在这里插入图片描述
一个类的大小中只保存成员变量,成员函数存放在公共代码区

其实可以理解,方法是同类对象公用的,但是属性是各有不同。

我们再看一个特例:
在这里插入图片描述

结论:一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比
较特殊,编译器给了空类一个字节来唯一标识这个类。

下面附上结构体内存对齐规则:

  1. 第一个成员在与结构体偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
    VS中默认的对齐数为8
  3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

this指针

引入

有了对上面的类的计算的了解后,这个this指针就多一层理解(为什么方法能够是对象们共用的)。

这个this指针也只出现在成员函数中。

我们首先引入一个问题:

#include using namespace std;class Person{public:void func(int age){age = age; // 注意之处}private:int age;};int main(){Person p1;p1.func(3);return 0;}

这个func()的功能就是给对象赋值,但是上面的代码逻辑上是错误的。

age = age;我们希望前面的age是对象属性,其实是参数age

我们除了可以通过修改形参(成员变量)名称解决问题外,还可以通过this指针来处理。

void func(int age){this->age = age;}

谁调用这个函数,我们就可以认为this指向了谁。

有了上面这个结论,我们就能明白,为什么函数可以是共有的。怎么区分是哪个对象在使用函数。就是通过this指针。

C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

#include using namespace std;class Person{public:void func(int age){this->_age = age;}void show([Person* const this]) // [] 中的内容是代码中实际不存在的{[this->]_age = age; // 注意之处}private:int _age; // 属性换了个名称};int main(){Person p1, p2;p1.func(3);p2.func(6); p1.show();p2.show(); // 注意之处return 0;}

特性

1.this指针的类型:类类型* const
2. 只能在“成员函数”的内部使用
3. this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
5. this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递