一、类的默认成员函数
默认成员函数就是⽤⼾没有显式实现,编译器会⾃动⽣成的成员函数称为默认成员函数,它可以进行自动调用,无需使用者手动调用,比如后面介绍的构造函数就是用于给对象进行初始化,之前我们都要给一个类写Init函数,然后调用它给对象初始化,但是如果我们有默认构造函数,那么在创建对象时就会自动进行调用,非常方便
⼀个类,我们不写的情况下编译器会默认⽣成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载不重要,我们稍微了解⼀下即可,其次就是C++11标准还增加了两个默认成员函数:移动构造和移动赋值,这个我们后⾯再讲解。现在我们来学这6个默认成员函数,它们很重要,也⽐较复杂,我们要从两个⽅⾯去学习:
1. 我们不写时,编译器默认⽣成的函数⾏为是什么,是否满⾜我们的需求
2. 编译器默认⽣成的函数不满⾜我们的需求,我们需要⾃⼰实现,那么如何⾃⼰实现?
以下是这几个默认成员函数的基本作用,大家先认识认识,接下来的两篇文章我们就将它们一一剖析进行讲解,如下:
二、构造函数
构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象(我们常使⽤的局部对象是栈帧创建时开的空间),⽽是对象实例化时初始化对象
构造函数的本质是要替代我们以前Stack和Date类中写的Init函数的功能,利用默认构造函数能够⾃动调⽤的特点完美的替代Init函数,接着我们就从编译器默认生成的构造函数能做什么,以及如果默认生成的构造函数不够用,该怎么写构造函数两个方面来展开学习
1. 默认生成的构造函数能干什么?
1. 自定义类型:当我们不写构造函数时,编译器会默认⽣成一个构造函数,虽然我们看不到,但是编译器确实会进行生成,这个构造对内置类型成员变量的初始化没有要求,比如int、double等类型,这个默认生成的构造函数对它们进行初始化时没有要求,可能是随机值,也可能是0,要看编译器的具体实现
2. 而对于⾃定义类型的成员变量,自定义类型的成员变量就是一个类类型或者结构体类型的成员变量,比如我们之前在数据结构那里做过的一道题:使用两个栈实现队列的基本操作,在这个队列中就包含了自定义类型的两个成员变量栈,如下:
class Stack
{
//栈的实现...
};
class Queue
{
public:
//使用栈实现队列的各种方法放这里...
private:
//这里的st1和st2就是自定义类型的成员变量
Stack st1;
Stack st2;
};
上面演示的伪代码就是两个栈实现队列,可以看到,这里队列的两个成员变量不是int等内置类型,而是一个类类型,也就是自定义类型,那么对于自定义类型,编译器生成的构造函数会如何进行处理呢?
编译器会调⽤这些自定义类型成员变量的默认构造函数,用它们自己的默认构造函数对这些自定义类型的成员变量进行初始化,默认构造函数不止有编译器默认生成的构造函数,还有全缺省构造函数以及无参构造函数都属于默认构造函数,我们在后面怎么写构造函数部分讲解
如果这个自定义类型的成员变量,它没有自己的默认构造函数,那么编译器就会报错,要解决这个问题我们需要使⽤初始化列表,初始化列表我们在下一篇文章给大家进行讲解,因为稍微有点复杂,我们先学会基本知识再去学习初始化列表就要好多了
上面就是默认生成的构造函数的所有行为,**总结一下:**如果是内置类型的成员变量,默认生成的构造函数的处理是由编译器决定,有可能是随机值,也可能是0,如果是自定义类型的成员变量,默认生成的构造函数会调用这个自定义类型的默认构造,如果这个自定义类型没有默认构造编译器就会报错
那么很显然编译器默认生成的构造函数肯定不够我们使用,所以我们大部分情况还是需要自己来写构造函数,接下来我们来讲讲怎么写构造函数
2. 怎么写构造函数
我们在写构造函数之前,要先了解手写构造函数的特点以及一些注意事项,所以我们先简单列举一下,如下:
1. 构造函数的函数名与类名相同,比如类名为Date,那么构造函数的函数名为Date()
2. 构造函数⽆返回值,也就是它的返回值啥都不需要给,也不需要写void,不要纠结,C++规定如此
3. 对象实例化时编译器会⾃动调⽤对应的默认构造函数,也就是当创建一个对象时,编译器会自动调用默认构造函数,不需要我们手动进行初始化操作,非常方便
4 构造函数可以重载,也就是只要参数不同,我们可以有多个构造函数,它们的函数名都是类名,在调用时会根据参数自动确认调用哪个构造函数
5. 如果类中没有显式定义构造函数,则C++编译器会⾃动⽣成⼀个⽆参的默认构造函数,一旦用户显式写了构造函数那么编译器将不再⽣成
上面就是手写构造函数的注意事项,当然还有几点比较重要的我们放在后面,现在根据上面的5条规则我们就可以实现构造函数了,现在我们来写一个日期类的无参构造函数,就是这个构造函数不需要任何参数,默认全部初始化为2025年1月1日,如下: