面试题答案
一键面试- 异常处理策略
- 基类析构函数:
- 基类析构函数通常不应抛出异常。因为当一个对象在析构过程中抛出异常,而此时析构函数已经在处理另一个异常(例如派生类析构函数抛出异常),就会导致程序调用
std::terminate
。基类析构函数应捕获并处理派生类析构函数传递上来的异常,或者将异常转化为日志记录等操作,避免异常向上传播。
- 基类析构函数通常不应抛出异常。因为当一个对象在析构过程中抛出异常,而此时析构函数已经在处理另一个异常(例如派生类析构函数抛出异常),就会导致程序调用
- 派生类析构函数:
- 派生类析构函数如果可能抛出异常,应尽量在内部处理。例如,可以使用
try - catch
块捕获异常,在catch
块中进行资源清理(如关闭文件、释放内存等),然后可以选择记录异常信息(例如使用日志库),避免异常直接抛出。如果确实无法处理,也应尽量转化为更易于处理的异常类型再抛出。
- 派生类析构函数如果可能抛出异常,应尽量在内部处理。例如,可以使用
- 基类析构函数:
- 保证资源正确释放
- RAII(Resource Acquisition Is Initialization)原则:
- 在 C++ 中,使用 RAII 技术是保证资源正确释放的关键。每个资源在对象构造时获取,在对象析构时释放。例如,对于动态分配的内存,可以使用
std::unique_ptr
或std::shared_ptr
来管理,这样在对象析构时,智能指针会自动释放其所管理的内存。对于文件资源,可以使用std::ifstream
或std::ofstream
,它们在析构时会自动关闭文件。 - 在多层继承体系中,每个派生类对象构造时,会先调用基类构造函数,基类构造函数获取其需要的资源,然后派生类构造函数获取其自身资源。析构时顺序相反,派生类析构函数先释放自身资源,然后基类析构函数释放基类资源。只要每个类都遵循 RAII 原则,资源就能正确释放。
- 在 C++ 中,使用 RAII 技术是保证资源正确释放的关键。每个资源在对象构造时获取,在对象析构时释放。例如,对于动态分配的内存,可以使用
- 异常安全的资源释放:
- 当派生类析构函数抛出异常时,仍然要保证已经获取的资源被正确释放。例如,如果在派生类中打开了一个文件并在析构函数中关闭,如果析构函数在关闭文件时抛出异常,应确保文件在异常发生前已经被正确关闭,或者在异常处理代码中进行正确的关闭操作。
- RAII(Resource Acquisition Is Initialization)原则:
- 对多态析构的影响
- 虚析构函数:
- 基类的析构函数设置为虚函数,是为了确保在通过基类指针或引用删除派生类对象时,能够正确调用派生类的析构函数。在多层继承且包含虚析构函数的体系中,当通过基类指针删除派生类对象时,会首先调用派生类的析构函数,然后依次调用其直接基类的析构函数,直到调用到最顶层的基类析构函数。
- 异常对多态析构的影响:
- 如果派生类析构函数抛出异常,会影响多态析构的正常流程。由于异常可能导致程序调用
std::terminate
,因此要尽量避免在析构函数中抛出异常。如果无法避免,应确保在异常处理过程中,仍然能够正确执行基类和其他派生类的析构函数,以保证整个对象层次结构的资源正确释放。例如,可以在派生类析构函数的try - catch
块中,在捕获异常后手动调用基类的析构函数(使用BaseClass::~BaseClass()
语法),确保基类资源也能正确释放。
- 如果派生类析构函数抛出异常,会影响多态析构的正常流程。由于异常可能导致程序调用
- 虚析构函数: