尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

深入理解C++ 类型转换<二>dynamic_cast

深入理解C++ 类型转换<二>dynamic_cast dynamic_cast是 C 中唯一一个在运行时进行类型检查的转换运算符。它专门用于处理多态类型即含有虚函数的类的继承体系主要解决父类指针/引用在运行时“到底指向的是哪个子类”的问题。核心特性依赖 RTTI运行时类型识别程序运行时会在内存中查询对象的类型信息因此有轻微的性能开销。严格的多态要求基类中至少有一个虚函数通常是虚析构函数否则编译会报错。安全的失败处理机制转换指针失败 → 返回nullptr转换引用失败 → 抛出std::bad_cast异常支持横向转换可以在同一继承层次的不同兄弟类之间转换只要它们有共同的虚基类。#include iostream #include exception // 捕获 bad_cast 异常 // 基类必须含有虚函数这里用虚析构函数否则 dynamic_cast 无法使用 class Animal { public: virtual ~Animal() default; // 虚析构是必须的 virtual void speak() const { std::cout Some animal sound std::endl; } }; // 派生类 Dog class Dog : public Animal { public: void bark() const { std::cout Woof! Woof! std::endl; } void speak() const override { std::cout Dog says: Woof! std::endl; } }; // 派生类 Cat class Cat : public Animal { public: void meow() const { std::cout Meow~ Meow~ std::endl; } void speak() const override { std::cout Cat says: Meow! std::endl; } }; int main() { std::cout 场景1: 安全的向下转换成功 std::endl; // 创建真实的 Dog 对象但用 Animal* 指向它 Animal* animalPtr new Dog(); // 运行时检查animalPtr 指向的到底是 Dog 还是其他 Dog* dogPtr dynamic_castDog*(animalPtr); if (dogPtr ! nullptr) { std::cout 转换成功animalPtr 确实指向 Dog可以调用 Dog 独有函数: ; dogPtr-bark(); } else { std::cout 转换失败 std::endl; } std::cout \n 场景2: 不安全的向下转换失败 std::endl; // 让 Animal* 指向 Cat 对象 Animal* animalPtr2 new Cat(); // 尝试将 Cat 转为 Dog这是错误的 Dog* wrongDogPtr dynamic_castDog*(animalPtr2); if (wrongDogPtr ! nullptr) { wrongDogPtr-bark(); // 不会执行到这里 } else { std::cout 转换失败animalPtr2 实际是 Cat不是 Dog返回 nullptr std::endl; } std::cout \n 场景3: 引用转换成功与失败 std::endl; Cat realCat; Animal animalRef realCat; // 父类引用绑定子类对象 // 引用转换成功因为 animalRef 确实绑定的是 Cat Cat catRef dynamic_castCat(animalRef); std::cout 引用转换成功: ; catRef.meow(); // 引用转换失败尝试将 Cat 转为 Dog 引用 try { Dog dogRef dynamic_castDog(animalRef); // 这里会抛异常 dogRef.bark(); // 永远执行不到 } catch (const std::bad_cast e) { std::cout 引用转换失败抛出 bad_cast 异常: e.what() std::endl; } std::cout \n 场景4: 兄弟类横向转换 std::endl; // 你有一只 Dog但想看看它能不能转成 Cat当然不能 Animal* animalPtr3 new Dog(); Cat* catFromDog dynamic_castCat*(animalPtr3); if (catFromDog nullptr) { std::cout 横向转换失败Dog 不能转换为 Cat std::endl; } // 释放内存生产环境建议用智能指针这里为简化手动 delete delete animalPtr; delete animalPtr2; delete animalPtr3; return 0; }
返回列表