基础知识铺垫:类和对象是什么
``
类class是由c语言struct结构体衍生出来.兼容struct的使用方法.但是两者略有不同.
类相当于建筑图纸,而对象是用该建筑图纸建成的房子.
图纸本身不能住人–>类没有开辟空间
房子能住人–>对象开空间
```#include<iostream>
using namespace std;
class Date//类
{
public://公开,外面可以访问
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private://私有,外面无法访问
int _year;
int _month;
int _day;//成员变量是声明,没有开空间
};
int main()
{
Date d1;//定义对象,开空间
return 0;
}
```js
构造函数能对类里面的成员变量进行自动初始化
构造函数出现的原因
忘记初始化的危害:我们在定义多个对象时,可能会忘记初始化.像上面那种日期的忘记初始化还好,只会生成随机值.
但如果你的成员变量中有指针,那就坏了.会有野指针的出现,让你的程序崩溃.
实现构造函数
{
public:
Date(int year=1, int month=1, int day=1)//构造函数
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Print();
Date d2(2023,12,27);
d2.Print();
return 0;
}
构造函数中的int year=1, int month=1, int day=1是缺省参数.在没有传参的时候year值为1, month值为1, day值为1.
类似于汽车的备胎,有需要才用它.
构造函数的特性:
1.没有返回值
2.函数名与类的名字相同
3.定义对象会自动调用构造函数
4.构成函数重载
函数重载是c++基于c改良出来的,函数重载就是函数名相同而参数不同.5.我们如果没有写构造函数,编译器会自己生成一个,但这个有缺陷.
首先我们要清楚:c++把类型分为内置类型:char,int之类的和指针.自定义类型:class,struct等自己定义的类型.
编译器自己生成的构造函数只处理自定义类型(会去调用这个类型的默认构造),不处理内置类型
默认构造包含三种:全缺省的默认构造
不传参的默认构造
编译器自己生成的
c++11打了补丁:支持声明时给缺省值.也就是第三种默认构造
class Date
{
public:
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year=1;
int _month=1;
int _day=1;
};
int main()
{
Date d1;
d1.Print();
return 0;
}
构造函数总结
1.一般情况下我们都要写构造函数
2.成员变量都是自定义类型或者内置类型给了缺省值可以考虑让编译器自己生成
析构函数
析构函数的功能与构造函数的相反.在对象的生命周期结束后会自动调用它,完成对象中资源的清理.
析构函数的实现
typedef int DataType;
class Stack//定义栈
{
public:
Stack(size_t capacity = 3)//默认构造函数
{
_array = (DataType*)malloc(sizeof(DataType) * capacity);
if (NULL == _array)
{
perror("malloc申请空间失败!!!");
return;
}
_capacity = capacity;
_size = 0;
}
~Stack()//析构函数
{
free(_array);
_array = NULL;
_capacity = 0;
_size = 0;
}
private:
DataType* _array;
int _capacity;
int _size;
};
int main()
{
Stack st1;
return 0;
}
析构函数的特性
1.析构函数的名字: ~+类名. 如:~stack
2.析构函数没有返回值和参数,所以析构函数没有重载函数
3.对象生命周期结束时,C++编译系统系统自动调用析构函数。
4.如果没有写析构函数编译器会自己生成,这个析构函数只处理自定义类型(会去调用这个类型的析构函数),不处理内置类型
class MyQueue
{
Stack pustst;
Stack popst;
};
int main()
{
MyQueue q;
return 0;
}
析构函数的总结
1.对象有动态开辟空间且成员变量为内置类型(指针)需要自己写析构函数.
2.成员皆为自定义类型可以不写析构函数