前言
📚作者简介:爱编程的小马,是一名大厂后端c++程序员。
📚本文收录于C++系列,本专栏主要是分享我所了解的c++知识,带领大家慢慢从了解c++到认识c++,持续更新!
📚相关专栏Linux正在发展,敬请期待!
📚本文主要内容:认识类和对象六个默认成员函数
今天所有的内容都会贯彻到咱们的日期类中 ,大家一定要自己敲一遍代码
目录
1.类的6个默认成员函数
如果一个类中什么成员都没有,简称为空类。空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员 函数。默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
分为构造函数,析构函数,拷贝构造函数,赋值重载函数,取地址重载函数(两个,一个是普通对象,一个是const对象),今天介绍前两个。
2. 构造函数
2.1 概念
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证 每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。
2.2 特性
其特性如下:
1、其函数名和类名相同
2、无返回值
3、构造函数可以重载
4、对象实例化自动调用构造函数
按照以上特性,先简单写一个日期类的构造函数
#include<iostream>
using namespace std;
class Date
{
public:
//类名和函数名相同
Date(int year , int month , int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2(2022, 03, 21);
return 0;
}
很多同学会这么写,这么写有什么问题?
编译器报错了,说没有可以使用的默认构造函数。这时候就有疑问了,我们不是写了一个构造函数吗?其实是这样的,无参的构造函数和全缺省的构造函数都称为默认构造函数,而我们这里是有参数的,所以不能称之为默认构造函数,应该加上缺省值。
5、如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。 那么我给大家演示一下,我不写,编译器会不会自己生成?
6、好像没有初始化呀?编译器生成了吗?为什么还是随机值呢?其实是这样的,C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类 型,如:int/char...,自定义类型就是我们使用class/struct/union等自己定义的类型,内置类型不做处理,自定义类型会去调用它的默认构造函数,比方说看下面的例子
#include<iostream>
using namespace std;
class Time
{
public:
Time()
{
cout << "Time" << endl;
_a = 0;
_b = 0;
}
private:
int _a;
int _b;
};
class Date
{
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;
//自定义类型
Time _t;
};
int main()
{
Date d1;
return 0;
}
结果自定义类型确实是自动的去调了一次他的默认构造函数。
7、无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。 注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。
3. 析构函数
3.1 概念
通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的? 析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由 编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
3.2 特性
析构函数是特殊的成员函数,其特征如下:
1.析构函数函数名是类名前加上~
2.无返回值,无参数
3.. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
4.在对象生命周期结束后自动调用
typedef int STDataType;
class Stack
{
public:
//构造函数
Stack()
{
cout << "Stack()" << endl;
STDataType* tmp = (STDataType*)malloc(sizeof(STDataType) * 4);
_a = tmp;
_capacity = 4;
_size = 0;
}
//析构
~Stack()
{
cout << "~Stack()" << endl;
free(_a);
_a = nullptr;
_size = _capacity = 0;
}
private:
STDataType* _a;
int _size;
int _capacity;
};
int main()
{
Stack s1;
return 0;
}
自动去调用构造和析构函数。
5. 关于编译器自动生成的析构函数,是否会完成一些事情呢?下面的程序我们会看到,编译器 生成的默认析构函数,对自定类型成员调用它的析构函数。
总结
本文从c++的默认成员函数切入,带大家了解了默认构造函数,默认析构函数,明天给大家更新拷贝构造函数和赋值重载函数。
如果这份博客对大家有帮助,希望各位给小马一个大大的点赞鼓励一下,如果喜欢,请收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给小马的意见,欢迎评论区留言