bosthhe1 / cpushpush

0 stars 0 forks source link

对于构造函数,析构函数,拷贝构造,初始化列表的初识 #5

Open bosthhe1 opened 1 year ago

bosthhe1 commented 1 year ago

image 构造函数是为了防止忘记初始化而设定的,默认的构造函数如果不自己实现,那么编译器就会默认实现构造函数,但是编译器实现的默认构造函数,并不会初始化内置类型,比如int,char,double,指针(任何指针都是内置类型),内置类型数组等,对于自定义类型入struct和class,会自动调用自定义类型的默认构造函数,来初始化自定义类型。 既然系统有默认的构造函数,就有自己实现默认的构造函数,默认的构造函数可实现函数重载。 自己实现默认的构造函数的书写形式是,函数没有类型,函数名和类型名同名,函数的参数要么没有形参要么全缺省)(以上没有参数的叫做默认构造函数,那么有默认构造函数就有非默认构造函数,这种非默认构造函数就叫做初始化列表,初始化列表是有参数的,当然写了初始化列表,就不会生成默认构造函数)(必须清楚默认构造函数和初始化列表的区别)。(默认构造函数和初始化列表和拷贝构造函数都属于构造函数,只要存在一个,默认的构造函数都不会自动生成,只能自己实现)(在后期我发现这里的表达错误,对于自定义类型会去调用他的默认构造,对于内置类型,没写构造函数,会默认生成,同时也可以只写一半,没写的部分编译器也会取自动初始化,比如一个类里面有int _a,int *b,我们构造函数只将_a初始化了,没初始化b,编译器也会给b默认初始化,这一点与虚函数表接轨) 这里的DATE就是默认的构造函数,DATE没有类型,DATE与类型名相同,参数全是缺省参数 image 这里就是构成函数重载,但是为了避免调用的时候存在二义性,建议写生全缺省参数,需要就传参,不需要就是默认值 image image

bosthhe1 commented 1 year ago

对于析构函数,基本上和构造函数一样 析构函数再程序结束的时候自动调用 对于内置类型不做处理,对于自定义类型会去调用它的析构函数 析构函数我们不写,系统会默认生成 析构函数的书写形式和构造函数相似,函数没有类型,函数名和类型名取反(~DATE),不能调用参数,所以析构函数不能函数重载 image

bosthhe1 commented 1 year ago

拷贝构造函数 拷贝构造函数如果不自己实现,系统默认会按照字节一对一拷贝(浅拷贝) 拷贝构造函数属于构造函数,所以只要写了拷贝构造函数,就必须写构造函数 拷贝构造函数,传参必须要传引用,不串引用会引发无穷递归(因为在c++里面,任何传值传参都需要拷贝,拷贝就需要去调用拷贝构造函数,但是拷贝构造函数如果是传值接收,会需要拷贝传值,则会引发无穷递归)(如果传引用就不会出现这种情况,引用就是函数的别名) 拷贝构造函数和this指针相关联 拷贝构造听名字就是拷贝其他同类型成员的参数来用作自己参数的初始化 拷贝构造的书写形式是,函数没有类型,函数名和类型名相同,有一个引用的参数,没有返回值 image 这里的看似只有一个参数,但是实际上有两个参数,一个是this指针(右边),一个是传过来的引用(左边)

bosthhe1 commented 1 year ago

我们需要清楚那些类是需要写构造函数和析构函数的,那些不需要,这个问题很抽象,比如说我们定义一个Stack的类,就需要初始化里面的值,如果我们用Stack去创建一个队列(两个栈实现一个队列),那么这个队列就不需要写构造函数和析构函数,因为对于自定义类型会去掉它的构造函数和析构函数,这里看到,本身Queue就是调用Stack的类,没有参数需要初始化,所以不需要相对的函数,但是Stack是自己实现的,是需要调用相对的函数 image

bosthhe1 commented 1 year ago

初始化列表(成员变量实力化的地方) image 初始化列表也是构造函数中的一种,但是没有默认参数,必须传参数来进行初始化,初始化列表的书写格式为以分号‘:’开头,逗号间隔,最后一个变量不写逗号,并写在括号的前面 初始化列表的作用 在我们进行成员变量的定义的时候,如果定义了引用或者const类型或者没有默认构造函数的自定义类型,或者使用了其他类的成员(这个在下个评论单独讲解),这些必须初始化的成员变量,引用和const和没有默认构造函数的自定义类型在定义出来的时候就必须要初始化,但是我们在成员变量定义的时候是无法完成的,就有了初始化列表,初始化列表可以对引用和const和自定义类型进行初始化(小知识点:const修饰的变量,会变为是常量,常量就必须在定义的时候初始化,只有一次初始化的机会) 我们可以看到默认构造函数是不可以对引用(i)进行初始化的,会报错,报错的原因是使用了未初始化的成员变量 image 这里的初始化列表可以对引用(i)进行初始化 image

bosthhe1 commented 1 year ago

没有默认构造函数的自定义类型这个是什么意思呢, 我们前面知道每个类,都有自己的构造函数,但是这个构造函数时默认生成的,对内置类型不做处理,对自定义类型会去调用它的默认构造函数,使用起来很不方便,所以我们一般会自己实现默认构造函数,来初始化一些变量,这个默认构造函数一般是全缺省参数作为构造环境,只要我们不传参数,就会默认使用缺省参数,完成初始化 存在默认构造函数,为全缺省值,就存在全部都为形参的构造函数,这种构造函数我们称为初始化列表,所以书默认构造函数和初始化列表是同一类东西,都是为了完成初始化 那么没有默认构造函数的自定义类型,意思就是这个成员变量的类型时自定义的,同时这个自定义的成员变量他的构造函数为初始化列表(需要传参),我们在默认的构造函数里面,是无法实现给自定义类型的初始化列表传参的,所以我们需要初始化列表来初始化没有默认构造函数的自定义类型。 以下是使用初始化列表初始化没有默认构造函数的自定义类型的成员变量 image image 如果我们用默认构造函数来初始化,这里会报错,因为默认构造函数对于自定义类型会去掉他的默认构造函数,但是类型a没有默认构造函数,而是初始化列表,所以会显示a没有默认构造函数 image

bosthhe1 commented 1 year ago

由于this指针是非静态成员函数默认传递的,存在于寄存器里面,this指针在非静态的成员函数里面,对象里面不存在this指针,this指针是调用非静态成员函数,编译器生成的