构造函数
在C++中,内置类型也有默认构造函数。比如匿名对象:int()默认是0 char()默认是\0 float默认是0.0
C++中有6个默认的成员函数(就是不写,编译器会自动生成):
为了解决经常忘记初始化和释放空间的问题,就有了构造函数和析构函数
构造函数:构造函数是特殊的成员函数,作用是初始化对象
构造函数的目的是希望在创建对象的时候就已经完成了初始化(自动调用构造),析构函数的目的,在对象的生命周期结束的时候,自动析构,也就是Destory,就不会造成内存泄漏(不释放内存,就会一直堆在那里,内存就会越来越少)的问题
1.函数名与 类名相同
2.无返回值(不用写void)
3.对象实例化编译器自动调用对应的构造函数(如下图,在创建对象的时候,就自动调用构造完成初始化)
4.构造函数可以重载(重载:函数名相同,参数不同。本质上就是可以进行写多种构造函数,对类对象进行多种初始化方式)
构造函数的调用方式是在对象的后面。为什么?因为是对这个对象进行初始化,特殊的函数,所以和一般函数调用不一样,一般的函数调用是 函数名(参数)【分为有返回值和没有返回值,有返回值的用变量接收,没有返回值的是void,是一种对数据的操作(例如数据结构中链表的初始化和销毁函数,主要是实现结果。】 如上图,构造函数是 如果有参数的话: 类名 对象名 (参数);如果没有参数是: 类名 对象名
在使用构造函数的时候,使用全缺省参数是一个很好的初始化方式。构造函数可以没有参数,也可以有参数,也可以全缺省,因为全缺省的函数调用方式和无参的函数调用方式相同,所有这两种构造函数不能同时存在
5.C++把类型分为内置类型和自定义类型。内置类型就是语言提供的数据类型,所有指针都是内置类型,比如类指针。自定义类型就是class,struct,union等用户自己定义的类型
构造函数也是默认成员函数,我们不写,编译器就会自动生成一个无参的构造函数,我们写了构造函数,编译器就不会生成(没太大用,一般还是自己写)。内置类型的成员不会处理,不会对内置类型的成员变量进行初始化,只会给随机值(C++11改进了,可以在成员变量声明处给缺省值)。
自定义类型的成员才会处理,不用显示的写构造函数,编译器会自动去调用这个成员的默认构造函数(举个例子:结构体是自定义类型,结构体是由很多个内置类型成员组成的,当一个结构体是类的成员变量时,对其进行初始化不需要写构造函数,编译器会自动去到这个结构体的定义处,使用它的初始化值)
所以,一般都是自己写构造函数决定初始化方式,如果成员变量全部都是自定义类型,可以不写
6.默认构造函数只能有一个,因为这三个调用方式相同,调用的时候会出现歧义。(注意与默认成员函数区分)。默认构造函数包含3种:没写编译器自动生成的,全缺省构造函数,没有参数的构造函数,总结:不需要向构造函数传参的 如下图,三种默认构造函数的例子
无参构造
全缺省构造
不写构造,编译器自动生成
析构函数
对象在函数里面(局部变量),栈帧结束对象就跟着销毁了,不需要清理,出了作用域栈帧会带走
开辟的空间在栈帧结束后要进行清理,不然会造成内存泄漏→需要析构函数
对象生命周期结束时,系统自动调用析构函数,资源清理工作(malloc的,fopen的),后定义的先析构
构造函数本质上相当于Init函数,进行初始化,析构函数与它相反,本质上相当于Destory函数,完成资源的清理工作
析构函数的函数名是在类名前面加一个~
析构函数无参数无返回值类型
如果没有写析构函数,编译器会自动生成一个,但是这个默认析构函数对内置类型的成员不会处理,自定义类型的成员才会处理,会去调用这个成员的默认析构函数
一个类只能有一个析构函数
内置类型不处理是什么意思?构造函数和析构函数的用法是一样的,在C++中,定义一个类变量就必须进行一次构造(初始化)和一次析构(资源释放),每次都会自己写构造和析构。如果不写,编译器就会自动生成一个,这个默认生成的构造和析构,都是对内置类型不处理,对自定义类型调用它的默认构造析构函数。具体来说,一个类的成员变量,是int double int*等等这种内置类型时,编译器生成的构造析构函数不会对它们进行初始化和资源释放,因为它们本来就是局部变量,在栈帧空间中,出了作用域就会释放。而一个类的成员变量中,有Stack或者Date 这种自定义类型的变量时,编译器生成的构造析构函数会去调用它们各自的定义处的构造析构函数(这两个都是类变量,是类变量就必然有构造和析构),有几个这样的类成员变量就会调用几次它们的构造析构函数。总之,最重要的是构造和析构都是自动调用,只要定义类变量就自动带这两个