构造函数
构造函数是一种特殊的成员函数,需要注意它的作用并不是开辟空间创建对象,而是在对象实例化时初始化对象,它有六大特点:
- 函数名与类名相同
- 无返回值(并非是指返回值为void,而是什么都不需要写)
- 在对象实例化时系统会自动调用构造函数
- 构造函数也可以重载
- 如果类中没有显示地定义构造函数的话,系统会默认生成一个无参的构造函数,而一旦用户显示地定义构造函数后,系统就不会再默认定义
- 用户显示定义的无参构造函数,系统默认的无参构造函数和用户定义的全缺省构造函数都叫做默认构造函数,但是这三个只能有一个存在而不能同时存在,否则会出现歧义,例:
#include<iostream>
using namespace std;//这里的展开仅为方便,项目中不建议展开
class Data
{
public:
//无参构造函数
Data()
{
_year = 1;
_month = 1;
_day = 1;
}
//有参构造函数
Data(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
//全缺省构造函数
//注意这里并没有屏蔽掉缺省函数
Data(int year = 2024, int month = 7, int day = 11)
{
_year = year;
_month = month;
_day = day;
}
void print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data a;//这里注意,当系统编译这条指令时,无法确定这里要求调用的是无参构造函数还是全缺省构造函数,所以程序会报错崩溃
Data b(2024, 7, 11);
a.print();
b.print();
return 0;
}
运行结果如下:
析构函数
析构函数的功能与构造函数相反,但它也并不是用来销毁对象,而是完成对对象中资源的清理释放工作,例如当对象中使用malloc动态申请了内存资源后,在对象使用结束或者程序结束时就需要析构函数来清理释放对象所申请的内存资源
析构函数主要有六个特点:
- 析构函数名是在类名前加符号 ~
- 无参无返回值(无返回值与构造函数类似,同样不需要加void)
- 一个类只能有一个析构函数,如果用户没有显示定义,系统会默认生成一个析构函数
- 在对象声明周期结束时,系统会自动调用析构函数
- 当用户创建的类里包含其他自定义类型成员时,无论是否显示地写析构函数,当声明周期结束时都会调用自定义类型成员的析构函数
- 类似于栈的结构特点,C++规定,在一个局部域的多个对象,先定义的后析构
举一个简单的例子:
typedef int STDataType;
class Stack
{
public:
Stack(int n = 4)
{
cout << "构造函数启动" << endl;
_a = (STDataType*)malloc(sizeof(STDataType) * n);
if (_a == nullptr)
{
perror("Stack::malloc fail!");
return;
}
_top = 0;
_capacity = n;
}
~Stack()
{
cout << "析构函数启动" << endl;
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
private:
STDataType* _a;
int _top;
int _capacity;
};
class MyQueue
{
public:
//这里即使显示地写了析构函数也会调用st1与st2的析构函数
~MyQueue()
{}
private:
Stack st1;
Stack st2;
};
int main()
{
Stack st;
MyQueue queue;
return 0;
}
输出结果如下: