类和对象(2)

类和对象

前言

类里面有默认成员函数。

默认成员函数,是用户没有实现,编译器默认生成的成员函数。

默认成员函数,有6个。

而我们关心的是两点:

  1. 编译器默认生成函数的行为是什么(编译器干了什么)?是否满足我们的要求?
  2. 如果不满足,我们自己实现,那我们如何实现?

1、构造函数

构造,不是创建,因为一个类类型空间的开辟,不需要构造函数去管。

构造函数,是完成初始化对象的函数。功能类似Init()函数。


为什么不在外面另外写一个Init()函数,而是使用构造函数?


因为Init()函数是分离的,如果有人忘了写Init()函数,会出事。

而构造函数的使用,保证了对象被实例化的时候,顺便也被初始化。

构造函数,是一个特殊的成员函数,不能用以往函数的思维去理解它:

1.1、函数名与类名相同

构造函数的函数名与类名相同。


1.2、没有返回值

构造函数没有返回值。返回值不需要给,也不需要void,C++的规定就是这样。

1.3、支持函数重载

构造函数可以重载。

1.4、调用对应构造函数

对象实例化时,系统会调用对应的构造函数。因为一个对象,可能需要多种初始化方式。


这里顺带一提:

如果d2的参数匹配不上,编译器会报错。

如果d1加上小括号,系统就会认为这是函数的声明,也会报错。所以,没有参数,不用括号。

1.5、无参的默认构造函数

如果类中没有显示定义构造函数,那么C++编译器会自动生成一个无参的默认构造函数。


而只要用户显示定义了一个构造函数,无论带参与否,编译器都不会再自动生成了。

1.6、什么是默认构造函数

不传递实参,就可以调用的构造函数,叫做默认构造函数。


用户显示定义的无参构造函数全缺省构造函数 ,用户不定义时编译器默认生成的构造函数,都是默认构造函数。而编译器默认生成的构造函数,才属于默认成员函数。


这三个默认构造函数,只能存在一个,不然会有调用歧义。

1.7、初始化与否

补充:


C++把数据类型分为内置类型(基本类型)和自定义类型。
用户不显示定义,编译器默认生成的构造函数,对内置类型的成员变量,没有初始化的要求。

在这里,初始化或不初始化是不确定的,这取决于编译器。


对于自定义类型的成员变量,则要求调用这个成员变量的默认构造函数。如果一个成员变量没有默认构造函数,就会编译报错。


如果我们把内置类型变量和自定义类型变量放在一起:

会发现,内置类型变量也跟着初始化了。

我们只要当成内置类型不会被处理就可以了。

2、析构函数

析构函数与构造函数相反。

析构函数不是为了完成对对象本身的销毁。

析构函数的核心功能,是完成对象中资源的清理工作。


析构函数的作用,类似栈中Destroy()函数,用于释放动态申请的空间。

而像Date类这样,没有什么资源可以释放,严格上来说,不需要析构函数。

2.1、"~" + 函数名

析构函数的函数名,是类名前加上"~"。

2.2、无参数无返回值

析构函数,没有参数,没有返回值

2.3、析构只有一个

一个类只能有一个析构函数。若未显式定义,系统会自动生成一个默认的析构函数。

2.4、系统的自动调用

对象生命周期结束时,系统会自动调用析构函数:

此时,析构在d1对象的生命周期结束后自动调用,无需显示调用。

2.5、后定义先析构

d1和d2,谁先调用析构函数呢?利用this指针看一下:

d2先调用析构函数处理。

后定义的对象,先调用析构函数。

2.6、Stack的析构函数

由于Stack创建对象的过程中,进行了动态申请空间,所以建议自行定义一个析构函数:

2.7、处理与否

与构造函数类似,用户不显示定义,编译器默认生成的析构函数,不会处理内置类型的变量。


而对于自定义类型的变量,则会调用其对应的析构函数。



其中,前两个析构函数,是两个Stack类对象st1、st2结束生命周期时调用的,

后两个析构函数,是MyQueue类对象q生命周期结束时调用的,用来清理q中的_pushst、_popst。

2.8、自定义必析构

自定义类型成员,无论什么情况,都会调用它的析构函数。这是为了保证资源不被泄露。

2.9、写析构分情况

如果类中没有资源被申请,可以不写析构函数,直接用默认的。比如Date类。


如果默认析构函数可以用,也可以不写析构函数。比如MyQueue类。


如果类中有资源被申请,一定要写析构,否则会有资源泄漏的风险。比如Stack类。

相关推荐
余额瞒着我当琳2 小时前
C++--深拷贝三件套 + swap + 写时拷贝 + vector 扩容 + reserve
java·开发语言·c++
ShineWinsu3 小时前
对于C++:布隆过滤器(bloomfilter)的详细解析
c++·面试·位图·位运算·布隆过滤器·海量数据·比特位
牛油果子哥q7 小时前
C++内存模型与深浅拷贝万字详解:栈堆静态内存布局、深浅拷贝底层差异、内存泄漏根治、拷贝崩溃踩坑、手写深拷贝实战
java·开发语言·c++
大鹏的NLP博客7 小时前
通用 Linux 嵌入式板端 C/C++ ABI 与 Glibc 依赖治理规范
linux·c++·交叉编译
ysa0510307 小时前
c++常用自带函数用法与注意
c++·笔记·算法
鸿芯微控科技12 小时前
MFC模拟量信号异常怎么排查?0-5V、4-20mA接线与量程换算
c++·5g·mfc·故障排查·质量流量控制器·4-20ma·模拟量信号
三十岁老牛再出发12 小时前
08.18每日总结
c++·python·numpy·pandas
余额瞒着我当琳13 小时前
C++--vector底层,leetcode118杨辉三角实战,对于传统reserve的坑点,迭代器失效
开发语言·c++
醉城夜风~14 小时前
(超详细)C++多态(Polymorphism)
开发语言·c++
小小龙学IT14 小时前
现代 C++ 内存管理与资源安全深度解析:从 RAII 到所有权模型
c++·安全