专业编程基础技术教程

网站首页 > 基础教程 正文

C++_类和对象_C++多态_虚析构和纯虚析构函数---C++语言工作笔记

ccvgpt 2024-11-12 09:54:09 基础教程 481 ℃


C++_类和对象_C++多态_虚析构和纯虚析构函数---C++语言工作笔记

?


?


然后我们再来看,虚析构和纯虚析构函数的用法,上面有大体的介绍了.


?


但是我们还是用一个例子来说明一下更好.


首先,我们去创建一个Animal类,类中我们去写上一个spreak这个,纯虚函数,然后,让我们的


Animal类,变成一个抽象类.


?


然后我们去写一个子类Cat,让子类Cat,去继承Animal这个类.并且我们在


Cat子类中去重写父类中的spreak这个,纯虚函数.


?


然后我们再写一个测试方法test01,可以看到


这里我们用,父类的指针animal 去 指向了一个,子类的对象new Cat


然后,我们利用父类的指针,去调用了,spreak函数,然后


?


我们在main函数中,调用测试方法test01,然后执行


?


看结果,没问题对吧,现在父类的指针,调用了子类的spreak函数.


?


上面都是我们以前学的


现在我们在子类Cat类中,添加一个m_Name这个,属性.


?


然后我们把这个m_Name这个属性,声明为一个指针.


?


然后我们去写一个Cat子类的构造函数,然后,通过new的方式,来


把传入的name参数的值,在堆区中创建一个字符串对象,然后返回一个指针,赋值给Cat类的m_Name


属性.


?


然后我们去修改一下,Cat类中实现的父类中的spreak函数,添加上,


m_Name


?


但是这里要注意,因为我们的m_Name是一个指针,所以这里,我们要解引用,使用*m_Name,解引用以后,就可以获取m_Name指针,指向的堆区中的具体的字符串内容了.


?


可以看到,因为我们用到字符串了,所以这里我们需要,引入string包


?


然后我们去写一个测试方法test01


里面,我们使用animal这个父类的指针,去指向一个,创建的Cat子类的对象.


然后,我们用父类的指针去调用,spreak函数,这里还要注意,


因为我们使用了堆区创建对象,所以用完指针以后,一定要,手动的去释放,


指针指向的堆区的内存空间.



然后执行看结果,没问题,父类的指针成功调用了,子类实现的父类中的纯虚函数spreak函数.


?


可以看到,上面是我们在Cat子类中,添加的构造函数


在构造函数中,我们给指针,m_Name,赋值了.但是我们怎么给这个指针释放


对应的堆区中的内存呢.


?


可以这样,我们可以给Cat类,添加一个~析构函数,在析构函数中,我们


写上上面的代码,来释放指针m_Name指向的堆区的内存空间.


?


然后我们再添加一行打印内容,方便我们查看执行过程.


?


我们在Cat子类的构造函数中,也写一个打印输出.方便我们查看执行过程


?


然后我们在父类中,的析构函数和构造函数中,也写上打印输出,方便我们查看


执行过程.


?


可以看到执行结果,首先,当我们用,父类的指针,指向一个新创建的Cat子类的堆区对象的时候.


先走了父类的构造函数,然后走了,子类的构造函数


然后,我们利用父类的指针animal去调用spreak函数的时候, 走了,子类中对父类中spreak函数的


实现方法.




然后,我们预想的应该是再去执行,子类的析构函数对吧,但是却没有执行,这样导致,子类中,


我们写的释放,堆区对象的析构函数,就没有执行,这样,堆区对象,就没有释放成功.就会有问题




子类的析构函数没有走,先走子类,再走父类才对.为什么会这样呢,怎么解决呢


?


上面写了原因,父类这种在析构的时候,不会调用子类中的析构函数,


这样的话,如果子类中有在堆区的属性,就会不能及时的释放,最终导致内存泄露.


?


我们怎么解决呢?


这个时候只需要在父类的,析构函数,前面加上,virtual关键字就可以了


?


我们再去执行看结果,可以看到没问题了对吧.


这里就是,利用虚析构函数,来解决,父类析构的时候不会调用,子类的,


析构函数,导致,子类中,会发生内存泄露的情况.


?


可以看到,上面也总结了


利用虚析构可以解决,父类指针释放子类对象时候不干净的问题


?


然后这个问题,实际上还可以用,另一种方法解决,就是利用纯虚析构函数,可以看到


上面,我们把父类中的,虚析构函数,改成了纯虚析构函数.


?


然后我们执行一下,可以看到报错了对吧.


?


为什么,因为父类中的纯虚析构函数,没有


实现对吧,我们说,纯虚函数需要实现才能用对吧.


可以看到,我们可以按照上面的方法,在类的外面,去实现父类的


纯虚析构函数.


?


然后我们再去执行看结果,可以看到也是可以的.



上面总结了,因为我们给父类添加了,纯虚析构函数,这样,父类就是一个抽象类了,


抽象类无法实例化对象.并且纯虚析构函数,也需要实现才行.


?




上面是做了些总结.


?

最近发表
标签列表