版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++析构函数面试题(基础+进阶+详细真题答案)说明:所有题目均为后端/客户端C++面试高频原题,答案通俗易懂、贴合面试官打分标准,无书面化空话,适配校招、社招面试场景。一、基础概念题(必问)1、什么是析构函数?它的作用是什么?参考答案:析构函数是类中特殊的成员函数,和构造函数成对出现,函数名和类名相同,前面加波浪号~,没有返回值、没有参数,且不能重载。它的核心作用是:在对象销毁时,自动释放对象占用的资源。主要处理两类资源释放:1)堆内存资源:构造函数中new出来的内存,必须在析构函数中delete,避免内存泄漏;2)系统资源:打开的文件句柄、网络套接字、锁资源、动态申请的缓冲区等,防止资源占用不释放。对象生命周期结束时,系统会自动调用析构函数,无需手动调用。2、析构函数的特点有哪些?(面试高频简答题)参考答案:1)函数名固定:~类名,无返回值、无参数,不支持函数重载;2)自动执行:对象销毁时由系统自动调用,程序正常结束、对象出作用域、delete堆对象都会触发;3)一个类只能有一个析构函数,不存在多个析构函数的情况;4)如果类中没有手动定义析构函数,编译器会自动生成一个默认析构函数,默认析构函数只会简单销毁成员变量,不会释放堆内存;5)析构函数的调用顺序和构造函数相反:先构造的后析构,后构造的先析构。3、默认析构函数和自定义析构函数的区别?参考答案:默认析构函数:编译器自动生成,内部为空,只会回收栈上的成员变量内存,不会释放new申请的堆内存,也不会处理文件、网络等系统资源。如果类中没有动态资源,使用默认析构函数完全没问题。自定义析构函数:开发者手动定义,核心是主动释放堆内存和各类系统资源。只要类中有动态申请的资源,就必须手动写析构函数,否则一定会产生内存泄漏。二、核心易错考题(面试重点)4、为什么析构函数最好定义成虚函数?参考答案(面试官最认可的标准答案):核心目的是解决多态场景下的内存泄漏问题。当父类指针指向子类对象,并且通过delete释放该对象时:1)如果析构函数不是虚函数,只会调用父类的析构函数,子类的析构函数不会执行,子类独有的动态资源无法释放,直接造成内存泄漏;2)如果析构函数是虚函数,会触发动态绑定,优先调用子类析构函数,再逐级调用父类析构函数,完整释放父子类所有资源。总结规则:只要类可能被继承,且存在父类指针操作子类对象的场景,必须将析构函数声明为虚函数。5、构造函数可以是虚函数吗?析构函数可以重载吗?参考答案:1)构造函数不能是虚函数。原因:虚函数的调用依赖虚函数表和虚指针,而虚指针是在对象构造过程中初始化的。对象还没构造完成时,没有虚表信息,无法实现虚函数调用,因此语法层面直接禁止构造函数虚化。2)析构函数不可以重载。原因:析构函数没有参数,也没有返回值,不满足函数重载的条件(参数列表不同),一个类只能有一个析构函数。6、栈对象和堆对象的析构函数调用时机有什么不同?参考答案:1)栈对象(局部对象):出当前作用域时,自动调用析构函数,无需手动干预,比如函数内部定义的局部类对象;2)堆对象(new创建的对象):不会自动调用析构函数,必须手动执行delete操作,才会触发析构函数。如果只new不delete,析构函数永远不执行,直接内存泄漏;3)全局对象:程序结束时,系统统一调用析构函数。7、析构函数可以抛异常吗?实际开发中为什么禁止?参考答案:语法上析构函数可以抛出异常,但工程中绝对禁止。核心原因:1)对象销毁时必然调用析构函数,如果析构函数抛异常且未捕获,程序会直接终止、崩溃;2)如果栈展开过程中多个对象析构,多个异常同时抛出,程序无法处理,直接宕机;3)资源释放失败属于兜底操作,不应该中断程序,实际开发中析构函数只做资源释放,内部必须捕获所有异常,不对外抛出。三、继承与多态高频真题8、继承场景下,构造函数和析构函数的调用顺序?参考答案:构造顺序:先父类,后子类先调用父类构造函数初始化父类成员,再调用子类构造函数初始化子类独有成员。析构顺序:先子类,后父类先销毁子类独有资源,调用子类析构函数,再调用父类析构函数销毁父类资源。口诀:先造父、再造子;先拆子、再拆父。9、纯虚析构函数是什么?有什么使用场景?参考答案:纯虚析构函数是被virtual修饰且赋值为0的析构函数,声明格式:virtual~类名()=0;。关键知识点(90%面试者答错):纯虚析构函数必须提供外部实现。因为子类析构时一定会调用父类析构函数,如果只有声明没有实现,链接阶段会报错。使用场景:需要定义一个抽象基类,禁止实例化对象,同时需要通过父类指针释放子类资源,此时使用纯虚析构函数。既可以让基类成为抽象类,又能保证多态析构的安全性。四、代码改错/分析题(手撕面试必考)10、分析以下代码的问题,并改正cpp
classBase{
public:
~Base(){}
};
classDerive:publicBase{
public:
int*p;
Derive(){p=newint[10];}
~Derive(){delete[]p;}
};
intmain(){
Base*b=newDerive();
deleteb;
return0;
}问题分析:父类析构函数非虚,通过父类指针delete子类对象时,只会调用父类析构函数,子类析构函数不执行,动态数组p的内存无法释放,造成严重内存泄漏。改正方案:将父类析构函数改为虚析构函数:cpp
virtual~Base(){};11、为什么智能指针的基类析构必须是虚析构?参考答案:智能指针本质是模板封装的指针管理类,底层会通过基类指针托管子类对象,最后通过delete释放资源。如果基类析构非虚,释放时无法调用子类析构函数,导致托管的对象资源泄漏。因此所有用于多态托管的基类,必须保证析构虚化,这也是开发中类继承的通用规范。五、高阶面试题(社招/进阶校招)12、explicit关键字、虚析构、默认析构的选型原则?参考答案:1)普通工具类、无需继承的类:直接使用默认析构函数,无需虚化,精简代码;2)需要被继承的基类:必须写虚析构函数,保证多态析构安全;3)抽象基类:使用纯虚析构函数,禁止实例化,同时保证析构正常调用;4)单参数构造函数加explicit,防止隐式类型转换,和析构函数配合保证类的封装安全性。13、析构函数中可以调用虚函数吗?会有什么问题?参考答案:语法上可以调用,但绝对不建议在工程中使用。原因:析构过程是先析构子类、再析构父类。当执行父类析构函数时,子类对象已经被销毁,此时调用虚函数不会触发动态绑定,只会调用父类的虚函数版本,不会执行子类重写的逻辑,极易产生业务逻辑错误、空指针异常。通用规范:构造函数、析构函数内部,禁止调用虚函数。14、什么情况下必须手动写析构函数?什么情况可以用默认?参考答案:必须手动定义析构函数的场景:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年秋招:中国进出口银行面试题及答案
- 2026年校招:福建机电控股公司面试题及答案
- 2026年秋招:中联重科笔试题及答案
- 2026年矿山安全管理人员安全教育培训方式创新课件
- 2026年秋招:中国卫星网络题库及答案
- 2026年校招:吉林水务投资集团面试题及答案
- 2026年重庆市北师大版五年级英语下册第4单元课后练习
- 2026年园区数字化高级运维师招聘笔试试卷 招录12人内部题库
- 2026年安全总监试题及答案
- 2026年滨州市检察院书记员考试练习题及答案
- 2026年北京市定向招录选调生录用考试真题及答案解析
- 2026年高等教育法学类自考-00261行政法学历年参考题库含答案解析
- 2026年初级会计职称考试基础试题(含解答)及答案
- 中国电动两轮车换电行业市场现状及投资态势分析报告(智研咨询)
- 2025年法考客观题考试真题及答案
- 公共部门经济学(第三版)
- 瀛海太和劳动服务有限责任公司招聘笔试题库2026
- 全息儿童体能训练
- 消防水池有限空间监理细则
- 业务跟单职责及流程制度
- 智能教室设备安装与调试方案
评论
0/150
提交评论