彻底搞懂虚函数之虚析构函数经典例题(牛客c++专项练习总结)

文章讨论了C++中的虚函数和虚析构函数的重要性。虚函数确保通过基类指针调用正确的子类方法,而虚析构函数防止了内存泄漏,保证在删除基类指针时正确调用派生类的析构。代码示例展示了如何使用这些概念,包括构造和析构的顺序以及如何通过强制类型转换安全地删除对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看题,读代码写结果

#include <stdio.h>
class CPerson{
public:
    virtual void Whoami() = 0;
};
class CStudent : public CPerson{
public:
    CStudent(){printf("student is created!\r\n");}
    virtual ~CStudent(){printf("student is destroy!\r\n");}
    virtual void Whoami(){printf("student!\r\n");}
};
class CTeacher : public CPerson{
public:
    CTeacher(){printf("teacher is created!\r\n");}
    virtual ~CTeacher(){printf("teacher is destroy!\r\n");}
    virtual void Whoami(){printf("teacher!\r\n");}
};
int main(){
    CPerson *pLily = new CTeacher();
    pLily->Whoami();
    delete (CTeacher *)pLily;
    CPerson *pLucy = new CStudent();
    pLucy->Whoami();
    delete pLucy;
return 0;
}
**思考写写看你的答案~**

1.先了解虚函数以及虚析构函数的作用:

虚函数的作用

在于通过父类的指针或者引用来调用它的时候能够变成调用子类的那个成员函数。

虚析构函数的作用

目的是基类的指针指向派生类对象,并用基类的指针删除派生类对象

2.再来了解一下构造函数和析构函数的作用顺序:

构造函数和析构函数的顺序就像盖房子和拆房子,最先被调用的构造函数,其对应的(同一对象中的)析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。

盖房子
1、基类构造函数执行。

2、派生类构造函数执行。

拆房子

3、派生类析构函数执行。

4、基类析构函数执行。

3.为什么要声明虚析构函数

基类指针可以指向派生类的对象(多态性),如果删除该指针delete []p;就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。

如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。所以,为了避免内存泄露,将析构函数声明为虚函数是十分必要的。

4.再来看一道题的答案

结果显而易见
在这里插入图片描述

5.分析代码

int main()  
  
   {  
  
   CPerson *pLily = new CTeacher();
   
//基类指针指向派生类  new 调用CTeacher类构造函数 打印teacher is created!*   
  
   pLily->Whoami();
  //调用CTeacher类的whoami成员函数 打印teacher!   
  
   delete (CTeacher *)pLily;
  //强制类型转换为Cteacher类指针 调用Cteacher类析构函数和抽象基类默认析构函数 打印                                                                                  //teacher is destroy!   
  
  CPerson *pLucy = new CStudent();
  
   pLucy->Whoami();
  
   delete pLucy;      //调用抽象基类默认析构函数,无打印内容  
  
   return 0;  
   }  

6.总结学习

从这里我们可以注意到,为了防止内存泄漏,即先析构派生类后析构基类,完成完全释放内存,可以通过:

①:虚化父类析构

即当基类指针可以指向派生类的对象,删除该指针delete []p,就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。

②:强转指针Delete

即将其强转为子类的指针再进行delete,则会先走子类析构,再走父类析构。

#创作不易,有什么不理解或者有什么错误的地方,欢迎一起交流
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值