C++异常处理面试必考:从入门到精通全解析,99%的候选人都在这里栽跟头!
本文已收录于《C++面试必考》专栏,覆盖字节、腾讯、美团等大厂高频考点。建议收藏+关注,后续持续更新。
一、前言
在C++面试中,异常处理是几乎必考的话题。无论是应届生还是五年经验的老兵,面试官总能在这里挖出你的知识盲区。
为什么异常处理这么重要?因为它直接关系到代码的健壮性、可维护性和性能表现。一个连try-catch都写不明白的候选人,面试官怎么敢把核心业务交给你?
本文将从基础到进阶,带你彻底搞懂C++异常处理的每一个细节。看完这篇,面试再也不慌。
二、异常处理基础:try-catch-finally
2.1 基本语法
C++的异常处理由三个关键字组成:throw、try、catch。
#include <iostream>
#include <stdexcept>
double divide(double a, double b) {
if (b == 0.0) {
throw std::runtime_error("除数不能为零!");
}
return a / b;
}
int main() {
try {
double result = divide(10.0, 0.0);
std::cout << "结果: " << result << std::endl;
}
catch (const std::runtime_error& e) {
std::cerr << "运行时错误: " << e.what() << std::endl;
}
catch (const std::exception& e) {
std::cerr << "标准异常: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "未知异常" << std::endl;
}
return 0;
}
关键点:
catch块按顺序匹配,先捕获派生类,再捕获基类catch(...)是万能捕获,放在最后作为兜底- 异常对象通过拷贝构造传递(C++11后可能是移动构造)
2.2 异常规范(Exception Specification)
C++11之前有throw(type)语法,C++11之后被noexcept取代:
// C++98 风格(已废弃,面试别用)
void func1() throw(std::runtime_error);
// C++11 风格(正确写法)
void func2() noexcept; // 承诺不抛异常
void func3() noexcept(true); // 同上
void func4() noexcept(false); // 可能抛异常(默认行为)
面试高频问题:noexcept的作用是什么?
- 编译器优化:标记
noexcept的函数,编译器可以做更多优化 - 移动语义:
std::vector扩容时,只有当移动构造是noexcept的,才会使用移动而非拷贝 - 程序安全:如果
noexcept函数抛出异常,程序直接调用std::terminate()终止
class MyVector {
public:
// 移动构造函数标记noexcept,vector扩容时才会用移动
MyVector(MyVector&& other) noexcept
: data_(other.data_), size_(other.size_) {
other.data_ = nullptr;
other.size_ = 0;
}
private:
int* data_;
size_t size_;
};
三、标准异常体系:你必须知道的家族树
C++标准库定义了一套异常类层次结构,面试经常考你"能说出几个标准异常":
std::exception
├── std::logic_error
│ ├── std::invalid_argument // 非法参数
│ ├── std::domain_error // 数学域错误
│ ├── std::length_error // 长度超限
│ ├── std::out_of_range // 范围越界
│ └── std::future_error // 异步操作错误
├── std::runtime_error
│ ├── std::range_error // 运行时范围错误
│ ├── std::overflow_error // 算术溢出
│ ├── std::underflow_error // 算术下溢
│ ├── std::regex_error // 正则表达式错误
│ ├── std::system_error // 系统错误
│ │ └── std::ios_base::failure // IO流错误
│ └── std::bad_any_cast // any类型转换失败
├── std::bad_alloc // 内存分配失败
├── std::bad_cast // dynamic_cast失败
├── std::bad_typeid // typeid空指针
├── std::bad_exception // 异常规范违反
├── std::bad_function_call // function空调用
└── std::bad_weak_ptr // weak_ptr构造失败
面试真题:std::logic_error和std::runtime_error的区别?
| 对比维度 | logic_error | runtime_error | <
|---|


58

被折叠的 条评论
为什么被折叠?



