行业数据网站,自助建站工具软件,办公室装修公司哪里好,济南做设计公司网站欢迎来到Cefler的博客#x1f601; #x1f54c;博客主页#xff1a;那个传说中的man的主页 #x1f3e0;个人专栏#xff1a;题目解析 #x1f30e;推荐文章#xff1a;题目大解析2 目录 #x1f449;#x1f3fb;类的默认6个成员函数#x1f449;#x1f3fb;构造… 欢迎来到Cefler的博客 博客主页那个传说中的man的主页 个人专栏题目解析 推荐文章题目大解析2 目录 类的默认6个成员函数构造函数内置类型和自定义类型与默认构造函数的关系缺省参数和构造函数的配合 析构函数 类的默认6个成员函数
实际上我们在声明一个类的时候编译器会默认生成6个成员函数。 默认成员函数用户没有显式实现即自己主动写编译器会生成的成员函数称为默认成员函数。
构造函数
概念 构造函数是一个特殊的成员函数名字与类名相同,创建类类型对象时由编译器自动调用以保证每个数据成员都有 一个合适的初始值并且在对象整个生命周期内只调用一次。 特性 构造函数的任务就是用来初始化成员变量
⚡️名字和类名相同⚡️无返回值⚡️在实例化对象时自动调用⚡️允许函数重载 class Date{public:Date()//无参构造函数{_year 1;_month 1;_day 1;}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(2023, 8, 5);return 0;}这里注意如果是设置无参构造函数实例化对象对象不能单单只给一个(). 因为编译器不知道你是声明函数还是声明变量。
⚡️如果类中没有显式定义构造函数则C编译器会自动生成一个无参的默认构造函数一旦用户显式定义编译器将不再生成。
内置类型和自定义类型与默认构造函数的关系
首先我们先了解下内置类型和自定义类型 内置类型诸如int、char、double等基本类型指针全部都是内置类型 自定义类型class、struct 、union…… 默认构造函数类的对象不需要传参就会自动调用的成员函数。
它们和默认构造函数的关系是什么呢 默认构造函数对内置类型不进行处理 默认构造函数会对自定义类型成员调用它的构造函数。 我们举个例子 class A1{public:A1(){a 1;cout a endl;}int a;};class A2{public:int b;A1 a1;};int main(){A2 var;cout var.b endl;return 0;}我们可以看到对于内置类型b,默认构造函数对其没有处理所以最后的结果是随机值。 但是a1是自定义类型它在被实例化对象为var时默认构造函数自动启动去调用它本身的构造函数所以它被初始化了。
但是到这里我们就会发现如果我们自己不显现一个构造函数那么内置类型的变量岂不是全都是随机值 所以在c11中为了补这个坑可以允许内置类型成员变量在类中声明时可以给默认值
缺省参数和构造函数的配合
无参的构造函数和全缺省的构造函数都称为默认构造函数并且默认构造函数只能有一个。 注意无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数都可以认为是默认构造函数。 class Date{public:Date()//无参构造函数{_year 1;_month 1;_day 1;}Date(int year 2023,int month 8 ,int day 5)//全缺省构造函数{_year year;_month month;_day day;}private:int _year;int _month;int _day;};上述中有无参构造函数和全缺省构造函数。 在语法上是没错的因为构造函数允许重载。 但是在实例化对象时会出错。 因为出现了两个默认构造函数所以编译器不知道用哪个。 除非这里给了实参可以让编译器知道用哪个默认构造函数才不会出问题。
如果这里有一个不是全缺省构造函数则另一个无参构造函数就是唯一的默认构造函数。 class Date{public:Date()//无参构造函数{_year 1;_month 1;_day 1;}Date(int year ,int month 8 ,int day 5)//有参构造函数{_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();return 0;}析构函数
概念 C中的析构函数是一种特殊的成员函数用于在对象被销毁时执行清理操作。析构函数的名称与类名相同但前面加上一个波浪号~。当对象的生命周期结束时例如对象超出范围、delete操作符被调用或程序退出析构函数会自动调用。
析构函数通常是用于释放动态空间上的资源。 特性
析构函数名是在类名前加上字符 ~。无参数无返回值类型。一个类只能有一个析构函数。若未显式定义系统会自动生成默认的析构函数。注意析构函数不能重载对象生命周期结束时C编译系统系统自动调用析构函数。与构造函数类似对内置类型不处理但会调用自定义类型成员的默认析构函数 注意创建哪个类的对象则调用该类的析构函数销毁那个类的对象则调用该类的析构函数 关于编译器自动生成的析构函数是否会完成一些事情呢下面的程序我们会看到编译器生成的默认析构函数对自定类型成员调用它的析构函数。
class Time
{
public:~Time(){cout ~Time() endl;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本类型(内置类型)int _year 1970;int _month 1;int _day 1;// 自定义类型Time _t;
};
int main()
{Date d;return 0;
}
程序运行结束后输出~Time()在main方法中根本没有直接创建Time类的对象为什么最后会调用Time类的析构函数 因为main方法中创建了Date对象d而d中包含4个成员变量其中_year,_month, _day三个是内置类型成员销毁时不需要资源清理最后系统直接将其内存回收即可 而_t是Time类对象所以在d销毁时要将其内部包含的Time类的_t对象销毁所以要调用Time类的析构函数。 但是main函数 中不能直接调用Time类的析构函数实际要释放的是Date类对象所以编译器会调用Date类的析构函 数而Date没有显式提供则编译器会给Date类生成一个默认的析构函数 目的是在其内部调用Time 类的析构函数即当Date对象销毁时要保证其内部每个自定义对象都可以正确销毁 main函数中并没有直接调用Time类析构函数而是显式调用编译器为Date类生的默认析构函数
所以如果类中没有申请资源申请动态空间时析构函数可以不写直接使用编译器生成的默认析构函数