默认成员函数:
定义:通俗的说就是当我们不写时,但是编译器会自己生成,而当我们自己写时,编译器就不会默认生成。
翻译:就是编译器的默认生成的函数,有些时候是不符合我们自己的要求的,因此需要我们自己去写。
一:构造函数(实际上就是对类的成员的初始化)
特征:
1.函数名与类名相同
2.无返回值
3.对象实例化时,编译器会自动调用对应的构造函数
4.构造函数可以重载-->提供多种初始化方式(注:当创建对象是无参时,不带括号,否则会与函数声明混乱)
5.编译器默认生成的构造函数不对内置类型处理(如int,char,int*........就是内置类型),而自定义类型会调用它的构造函数
针对内置类型成员不初始化的缺陷,又打了补丁,即: 内置类型成员变量在 类中声明时可以给默认值 。(int _day=1;)6.无参的构造函数和全缺省的构造函数,还有我们不写,编译器默认生成的构造函数都可以认为是默认构造函数(默认构造函数有且仅有一个否则会造成二义性)
class Date
{
public:
// 全缺省等同于无参,可以同时存在,但是会引起二义性
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
Date()
{
_year = 1;
_month = 1;
_day = 1;
}
private:
int _year;
int _month;
int _day;
};
int mian()
{
Date d1(2022, 9, 21);
Date d2(2022, 10, 17); //调用有参数构造函数
Date d3; //调用无参构造函数,不能带括号,否者会认为是函数声明
return
}
二:析构函数
概念:对象在销毁是自动调用析构函数,完成对对象中资源的清理工作
翻译:就是对开辟过空间的内存进行释放。
特征:
1.析构函数名是在类名前加“~”
2.无参数无返回值类型
3.一个类只能有一个析构函数
4.对象生命周期结束时,会自动调用析构函数
5.如果类中没有申请资源是,可以不写析构函数,直接使用编译器生成的默认析构函数,申请了资源的一定要写析构函数,否者会造成内存泄漏
//既有构造函数还有析构函数
class Stack
{
public:
//构造函数
Stack(int capacity = 4)
{
_a = (int*)malloc(sizeof(int) * capacity);//这是为什么既有构造还有析构函数
if (_a == nullptr)
{
perror("malloc fail");
exit(-1);
}
_top = 0;
_capacity = capacity;
}
//析构函数,因为申请了资源
~Stack()
{
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
private:
int* _a;
int _top;
int _capacity;
};