C++ 中的 dynamic_cast 是什么?
用途
- 在运行时在多态类型之间安全地进行转换
- 通常用于将基类指针转换为派生类指针(向下转型)
- 使用 RTTI(运行时类型识别)进行类型检查
基本语法
Derived* d = dynamic_cast<Derived*>(basePtr);
- 如果
basePtr实际指向一个Derived对象,则转换成功 - 否则,返回
nullptr
转换失败的情况
- 指针转换: 如果实际对象不是目标类型,则返回
nullptr - 引用转换: 如果失败,会抛出
std::bad_cast异常
指针向下转型示例
class Entity {
virtual ~Entity() {}
};
class Player : public Entity {};
class Enemy : public Entity {};
Entity* e = new Enemy;
Player* p = dynamic_cast<Player*>(e);
if (p) {
// 可以安全使用 p
} else {
// p 是 nullptr
}
引用向下转型示例
try {
Entity& e_ref = *new Enemy;
Player& p_ref = dynamic_cast<Player&>(e_ref);
} catch (const std::bad_cast& ex) {
// 捕获异常
}
派生类转基类(向上转型)
- 总是安全的
- 是隐式进行的,不需要转换语法
- 不需要使用
dynamic_cast
向上转型示例
class Entity {
virtual void say() {}
};
class Player : public Entity {
void jump() {}
};
Player p;
Entity* e = &p; // 隐式向上转型,安全
e-*gt;say(); // 正确
// e->jump(); // 错误:Entity 中没有 jump()
dynamic_cast 的使用条件
- 基类必须是多态类(至少有一个
virtual函数) - 只能用于指针或引用
- 编译器需启用 RTTI(大多数默认启用)
static_cast 与 dynamic_cast 比较
| 特性 | static_cast |
dynamic_cast |
|---|---|---|
| 编译期检查 | ✅ | ❌ |
| 运行期安全 | ❌ | ✅ |
| 失败时可检测 | ❌(行为未定义) | ✅(返回 nullptr 或抛出异常) |
| 需要虚函数 | ❌ | ✅ |
总结
- 在处理多态类时,使用
dynamic_cast进行类型安全的向下转型 - 对于指针转换,请检查是否为
nullptr;引用转换请使用 try-catch 捕获异常 - 派生类到基类的转换(向上转型)总是安全的,可隐式进行
C/C++编程
- 理解C++中的std::transform_reduce及示例
- 使用原子 TAS 指令实现自旋锁
- C++中检测编译时与运行时: if consteval 与 std::is_constant_evaluated()
- C++ 转发引用: 完美转发的关键
- 理解 C++ 中的 dynamic_cast: 安全的向下转型与向上转型
- C与C++: restrict关键字及其在编译器优化中的作用
- C++的左值/lvalue, 右值/rvalue和右值引用/rvalue references
- C++中的assert和static_assert的区别
- C++: auto_ptr智能指针被弃用
- C++中的consteval是什么? 它与const和constexpr有何不同?
- C++ 教程: 用std::move来移动所有权
- C++中的 const和constexpr 比较
- 简易教程: C++的智能指针
- C++ 编程练习题: 如何合并两个二叉树?
- C++ 编程练习题 - 找出第三大的数
- C++ 编程练习题 - 最多连续的 1
- C++ 编程练习题 - 左子树叶节点之和 (深度优先+广度优先+递归)
- C++ 编程练习题 - 最多水容器 (递归)
- C++的异步编程: std::future, std::async 和 std::promise
- C编程练习题: 翻转整数位
- C++编程练习题: 找出字符串的所有大小小组合
- C/C++ 中的内存管理器(堆与栈)
- C++编程练习题: 对两单向链表求和
英文:Understanding dynamic_cast in C++: Safe Downcasting Explained
强烈推荐
- 英国代购-畅购英伦
- TopCashBack 返现 (英国购物必备, 积少成多, 我2年来一共得了3000多英镑)
- Quidco 返现 (也是很不错的英国返现网站, 返现率高)
- 注册就送10美元, 免费使用2个月的 DigitalOcean 云主机(性价比超高, 每月只需5美元)
- 注册就送10美元, 免费使用4个月的 Vultr 云主机(性价比超高, 每月只需2.5美元)
- 注册就送10美元, 免费使用2个月的 阿里 云主机(性价比超高, 每月只需4.5美元)
- 注册就送20美元, 免费使用4个月的 Linode 云主机(性价比超高, 每月只需5美元) (折扣码: PodCastInit2022)
- PlusNet 英国光纤(超快, 超划算! 用户名 doctorlai)
- 刷了美国运通信用卡一年得到的积分 换了 485英镑
- 注册就送50英镑 – 英国最便宜最划算的电气提供商
- 能把比特币莱特币变现的银行卡! 不需要手续费就可以把虚拟货币法币兑换
微信公众号: 小赖子的英国生活和资讯 JustYYUK