C++---六个默认成员函数

类是一种将抽象转化为用户定义类型的C++工具,它将数据表示和操纵数据的方法组成一个简洁的包。

类的大小

实现来看一下什么都么有的类–空类
这里写图片描述
空类的大小为 1 ,这是为什么呢?
当创建一个空类时就要创建一个地址,来标识空类的地址,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址,所以空类所占的内存大小是1个字节。
这里写图片描述
非空类的大小是怎么计算的呢?
在计算类的大小时,和结构一样遵循内存对齐规则。
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
-
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
- VS中默认的值为8
- gcc中的默认值为4
- 结构体总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
为什么要进行内存对齐
我们的cpu把内存当成是一块一块的,块的大小可以是2,4,8,16 个字节,因此CPU在读取内存的时候是一块一块进行读取的,块的大小称为(memory granularity)内存读取粒度,按4或8字节对齐的雷和结构体才能有效的提高CPU读取率。

类的默认成员函数

  • 构造函数
  • 拷贝构造函数
  • 析构函数
  • 赋值运算符重载函数
  • operator &()取地址符重载
  • operator & () const const修饰的取地址符操作

构造函数

成员变量为私有的,要对它们进行初始化,必须用一个公有成员函数来进行。同时这个函数应该有且仅在定义对象时自动执行一次,这时调用的函数称为构造函数(constructor) 。
这里写图片描述

  • 函数名与类名相同
  • 没有返回值
  • 可以进行重载
  • 只能调用一次
  • 不能用const 和 virtual修饰
  • 当没有写构造函数时,编译器将自动产生一个缺省的构造函数
  • 应避免成员初始化成员,初始化的顺序是按照变量声明的次序进行的

拷贝构造函数

这里写图片描述

  • 拷贝构造函数其实就是构造函数的一种重载
  • 拷贝构造函数的参数必须使用引用传参,使用传值方式会引发无穷递归调用。因为拷贝构造函数的参数用传值,必须用拷贝构造函数拷贝一份,如此下去无穷递归了!加上const这样就能防止被修改了。
  • 若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会,依次拷贝类成员进行初始化。

析构函数

当一个对象的生命周期结束时,C++编译系统会自动调用析构函数。
这里写图片描述

  • 析构函数名与构造函数名类似,在前面加一个“~”符号
  • 析构函数没有参数,也没有返回值
  • 个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数
  • 对象生命周期结束时,C++编译系统系统自动调用析构函数
  • 基类的析构函数加上virtual关键字—采用虚析构函数避免内存泄漏。

虚析构函数:如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。

操作符重载

为了增强程序的可读性,合理的使用操作符重载。
重载操作符是具有特殊函数名的函数,关键字operator后面接需要定义的操作符符号。操作符重载也是一个函数,具有返回值和形参表。
这里写图片描述
不能被重载的运算符:

  • . 成员访问运算符
  • .*,->* 成员指针访问运算符
  • :: 域运算符
  • sizeof 长度运算符
  • ?: 条件运算符
  • # 预处理运算符

取地址操作符重载 & const修饰的取地址操作符函数

这两个函数一般不需要我们在进行重载,合理使用即可。

猜你喜欢

转载自blog.csdn.net/qq_37934101/article/details/81275969