this指针
类中的函数没有关于不同对象的区分,那该函数如何知道应该访问的是d1还是d2呢?
c++给了一个隐含的this指针解决这个问题。
this指针的特点:
- 编译器编译后,类的成员函数都会默认在形参的第一个位置,增加一个当前类型的指针。叫做this指针。
- 类的成员函数访问成员变量,本质上都是通过this指针来访问的。
- c++规定不能再函数的实参或者形参的位置显示地写this指针,但是可以在函数体内显示使用。
示例:
class Date
{
public:
//void Init(Date* const this,int year,int month,int day)隐含的this指针
void Init(int year,int month,int day)
{
_year = year;//也可以写为this->_year = year
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
}
int main
{
Date d1;
d1.Init(2024,7,16);
}
类的默认成员函数
在c++下,用户不显示实现,编译器会默认生成6个默认成员函数,分别是构造、析构、拷贝构造和复制重载。
构造函数
构造函数是一种特殊的成员函数,它的主要任务是在对象实例化时初始化对象,它的自动调用的特点完美替代了Init函数。
构造函数的特点:
- 函数名与类名相同
- 无返回值
- 对象实例化时会自动调用对应的构造函数
- 构造函数可以重载
- 如果类中没有显示的定义构造函数,编译器会自动生成一个无参的默认构造函数,一旦用户显示实现就不再生成。
- 无参构造函数,全缺省构造函数,默认生成的构造函数,这3个函数有且只能存在一个,不能同时存在,因为调用时会产生歧义。以上的无需传参的构造函数都成为默认构造函数。
- 编译器生成的默认构造函数对内置类型的成员初始化没有要求,是否初始化不确定,看编译器。
示例:
class Date
{
public:
Date()//无参构造函数
{
_year = 1900;
_month = 1;
_day = 1;
}
Date(int year=1900,int month=1,int day=1)//全缺省构造
{
_year = year;
_month = month
_day = day;
}
private:
int _year;
int _month;
int _day;
}
int main()
{
Date d1(2024,7,16);//调用全缺省参数
Date d2;//当无参构造函数与全缺省构造函数同时存在时,有歧义
}
析构函数
析构函数的作用与构造函数的作用相反,析构函数不是对对象本身进行销毁,而是完成清理释放工作,同样也是自动调用的。
析构函数的特点:
- 析构函数与类名相同,前面加上~
- 无参无返回值,不能重载
- 一个类只能有一个析构函数,如果没有,编译器会默认生成一个无参的析构函数
- 对象生命周期结束时,系统会自动调用析构函数
- 可以被继承,不能被重写
- 跟析构函数类似,编译器默认生成的析构函数对内置类型的成员不做处理,自定类型会调用它的析构函数。
- 如果类中没有申请资源时,析构函数可以不写。
示例:
class Stack
{
public:
Stack(int n = 4)
{
_a = (int*)malloc(sizeof(int)*n);
if(_a == nullptr)
{
perror("malloc fail");
return;
}
_capacity = n;
_top = 0;
}
~Stack()
{
free(_a);
_a = nullptr;
_capacity = _top=0;
}
private:
int* _a;
int _capacity;
int _top;
}
class Myqueue
{
public:
//编译器默认生成了Myqueue的构造函数调用了Stack的构造,完成了对两个成员的构造
private:
Stack pushst;
Stack popst;
}