591 字
2 分钟
【CPP】类型转换与异常
2026-03-27

为什么 C++ 需要新的转换方式#

C 风格 (Type)exprType(expr) 可在一次转换中完成多种语义(截断、指针转换、去掉 const 等),难以在代码中一眼看出意图,也不易在编译期拦截错误。

C++ 提供四种命名的转换,语义清晰、可检索。

四种 cast#

转换用途安全性
static_cast相关类型之间的编译期转换由程序员保证
dynamic_cast多态类型的运行时下行转换有 RTTI 检查
const_cast增加或去掉 const/volatile仅改 cv 限定,不改类型布局
reinterpret_cast比特级重新解释危险,极少使用

static_cast#

double d = 3.14;
int i = static_cast<int>(d);
Derived* pd = static_cast<Derived*>(pBase); // 下行:无运行时检查,不安全
  • 数值转换、显式调用单参数构造函数、无虚函数时的上行/下行指针转换。
  • 不能去掉 const(用 const_cast)。

dynamic_cast#

要求基类至少有一个 虚函数(多态类型)。

Base* pb = /* 指向 Derived */;
Derived* pd = dynamic_cast<Derived*>(pb);
if (pd) { /* 确实是 Derived */ }
try {
Derived& dr = dynamic_cast<Derived&>(*pb);
} catch (const std::bad_cast&) { /* 引用失败抛异常 */ }
  • 指针失败 → nullptr;引用失败 → std::bad_cast
  • 有运行时开销(RTTI)。

const_cast#

const int ci = 10;
int* p = const_cast<int*>(&ci);
// *p = 20; // 若 ci 在只读段,未定义行为

仅用于去掉/添加 const、volatile;不能改变除 cv 外的类型。

reinterpret_cast#

intptr_t addr = reinterpret_cast<intptr_t>(ptr);

用于指针与整数、无关类型指针之间;可移植性差,除非底层/互操作必需,否则避免。

父类转子类(原笔记要点)#

  • 上行(派生 → 基类):隐式、安全。
  • 下行(基类 → 派生):应用 dynamic_cast 或确保对象真实类型,避免 static_cast 盲目下行。

异常 (exception)#

异常:程序运行时出现的错误或非预期路径,通过 throw 抛出,沿调用栈展开,由匹配的 catch 处理。

double divide(double a, double b) {
if (b == 0) throw std::invalid_argument("division by zero");
return a / b;
}
try {
double r = divide(1, 0);
} catch (const std::invalid_argument& e) {
std::cerr << e.what() << '\n';
} catch (...) {
std::cerr << "unknown error\n";
}

机制

  1. try:可能抛异常的代码。
  2. throw:抛出对象(通常是 std::exception 派生类)。
  3. catch:按类型匹配;派生类 catch 须写在基类之前。
  4. 未捕获异常 → 调用 std::terminate

规范

  • const 引用捕获,避免切片:catch (const std::exception& e)
  • 析构函数默认 noexcept;析构中抛异常危险。
  • 资源管理配合 RAII,异常安全等级(基本/强/不抛)与智能指针、移动语义相关。

不宜用异常的场景:极热路径、嵌入式无异常支持的编译选项(-fno-exceptions)。

RTTI#

Runtime Type Identificationtypeiddynamic_cast 依赖运行时类型信息。可 -fno-rtti 关闭以减小体积(则 dynamic_cast 受限)。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【CPP】类型转换与异常
https://lysj.work/posts/studynotes/cpp/cpp类型转换与异常/
作者
Sekiro
发布于
2026-03-27
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录