news 2026/4/16 9:23:21

C++类型判断

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++类型判断

一、编译期类型判断(静态类型检查)

这类判断在编译阶段完成,零运行时开销,主要用于模板编程、类型萃取等场景。

1.typeid运算符(基础)

typeid可以获取类型信息,返回std::type_info对象,常用于判断两个类型是否相同。

代码示例

cpp

运行

#include <iostream> #include <typeinfo> // 必须包含此头文件 class Base {}; class Derived : public Base {}; int main() { // 1. 判断基本类型 int a = 10; double b = 3.14; std::cout << "type of a: " << typeid(a).name() << std::endl; // 输出:int(不同编译器可能简写,如i) std::cout << "type of b: " << typeid(b).name() << std::endl; // 输出:double(如d) // 2. 判断自定义类型 Base base; Derived derived; std::cout << "base type: " << typeid(base).name() << std::endl; // Base std::cout << "derived type: " << typeid(derived).name() << std::endl; // Derived // 3. 判断类型是否相同 if (typeid(a) == typeid(int)) { std::cout << "a is int type" << std::endl; } // 注意:非多态类型,指针/引用不会触发动态类型判断 Base& ref = derived; std::cout << "ref type: " << typeid(ref).name() << std::endl; // 输出Base(非多态) return 0; }

关键说明

  • typeid返回的name()结果是编译器相关的(比如 GCC 会简写类型名),不能直接依赖字符串内容判断类型。
  • 对于非多态类型(类中无虚函数),typeid仅判断编译期类型,不会解析实际指向的对象类型。
2. 模板类型萃取(C++11 及以上)

通过标准库的std::is_samestd::is_pointerstd::is_class等模板,在编译期精准判断类型属性。

代码示例

cpp

运行

#include <iostream> #include <type_traits> // 必须包含此头文件 template <typename T> void check_type(T value) { // 判断是否为指定类型 if constexpr (std::is_same_v<T, int>) { // C++17的is_same_v,等价于std::is_same<T, int>::value std::cout << "Type is int" << std::endl; } else if constexpr (std::is_same_v<T, double>) { std::cout << "Type is double" << std::endl; } // 判断类型属性 std::cout << "Is pointer: " << std::boolalpha << std::is_pointer_v<T> << std::endl; std::cout << "Is floating point: " << std::is_floating_point_v<T> << std::endl; std::cout << "Is arithmetic: " << std::is_arithmetic_v<T> << std::endl; // 算术类型(int/float等) } int main() { check_type(10); // int,非指针,非浮点,算术类型 check_type(3.14); // double,非指针,浮点,算术类型 check_type(&10); // int*,指针,非浮点,非算术类型 // 自定义类型判断 class MyClass {}; std::cout << "Is class: " << std::is_class_v<MyClass> << std::endl; // true return 0; }

关键说明

  • std::is_same<T, U>:判断 T 和 U 是否是完全相同的类型(包括 const/volatile 修饰)。
  • if constexpr(C++17):编译期条件判断,不会为不满足的分支生成代码,避免运行时开销。
  • 常用类型萃取模板:std::is_pointer(指针)、std::is_reference(引用)、std::is_const(常量)、std::is_base_of(基类判断)。

二、运行期类型判断(动态类型检查)

适用于多态类(含虚函数),在运行时判断对象的实际类型,核心是dynamic_cast

1.dynamic_cast类型转换(核心)

dynamic_cast用于多态类型的向下转换(子类→基类)或交叉转换,转换失败时:

  • 指针类型:返回nullptr
  • 引用类型:抛出std::bad_cast异常。

代码示例

cpp

运行

#include <iostream> #include <typeinfo> #include <exception> // 多态基类(必须有虚函数) class Base { public: virtual ~Base() = default; // 虚析构函数,使类成为多态 }; class Derived1 : public Base {}; class Derived2 : public Base {}; void check_dynamic_type(Base* ptr) { // 判断是否为Derived1类型 if (Derived1* d1_ptr = dynamic_cast<Derived1*>(ptr)) { std::cout << "Object is Derived1 type" << std::endl; } // 判断是否为Derived2类型 else if (Derived2* d2_ptr = dynamic_cast<Derived2*>(ptr)) { std::cout << "Object is Derived2 type" << std::endl; } else { std::cout << "Unknown type" << std::endl; } } int main() { Base* b1 = new Derived1(); Base* b2 = new Derived2(); Base* b3 = new Base(); check_dynamic_type(b1); // Derived1 check_dynamic_type(b2); // Derived2 check_dynamic_type(b3); // Unknown type // 引用类型的dynamic_cast(失败抛异常) try { Base& ref = *b2; Derived1& d1_ref = dynamic_cast<Derived1&>(ref); } catch (const std::bad_cast& e) { std::cout << "Cast failed: " << e.what() << std::endl; } delete b1; delete b2; delete b3; return 0; }

关键说明

  • dynamic_cast仅对多态类(含虚函数)有效,否则编译报错。
  • 运行时开销:dynamic_cast会查询类型信息表(vtable),有轻微运行时开销,应避免频繁使用。
2. 结合typeid实现动态类型判断

对于多态类,typeid会解析对象的实际类型(而非编译期类型):

cpp

运行

#include <iostream> #include <typeinfo> class Base { virtual ~Base() = default; }; class Derived : public Base {}; int main() { Base* ptr = new Derived(); std::cout << typeid(*ptr).name() << std::endl; // Derived(实际类型) delete ptr; return 0; }

三、常见使用场景

  1. 模板编程:用std::is_same/std::is_pointer等编译期判断,实现类型分支逻辑。
  2. 多态场景:用dynamic_cast判断基类指针 / 引用实际指向的子类类型。
  3. 类型安全检查:避免错误的类型转换(如将非多态类强制转换)。

总结

  1. 编译期判断:用std::is_same/std::is_pointer等模板(<type_traits>),零运行时开销,适合模板编程。
  2. 运行期判断:仅适用于多态类,用dynamic_cast(推荐)或typeid,有轻微运行时开销。
  3. 核心注意dynamic_cast依赖虚函数表,仅对多态类有效;typeid对非多态类仅返回编译期类型。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 18:20:50

手把手教程:用通义千问2.5-7B和vLLM实现代码补全功能

手把手教程&#xff1a;用通义千问2.5-7B和vLLM实现代码补全功能 1. 学习目标与前置知识 本文将带领读者从零开始&#xff0c;使用 通义千问2.5-7B-Instruct 模型结合 vLLM 推理框架&#xff0c;搭建一个高效的本地化代码补全系统。通过本教程&#xff0c;您将掌握&#xff1…

作者头像 李华
网站建设 2026/4/13 22:59:59

提示工程架构师经验:如何用Prompt解决客服复杂问题?

提示工程架构师经验&#xff1a;如何用Prompt解决客服复杂问题&#xff1f; 一、引言&#xff1a;客服AI的「尴尬时刻」&#xff0c;你遇到过吗&#xff1f; 上周晚饭后&#xff0c;我帮妈妈处理网购纠纷——她买的养生壶收到时底座裂了&#xff0c;联系客服AI得到回复&#xf…

作者头像 李华
网站建设 2026/4/16 9:22:42

AnimeGANv2实战:动漫风格社交媒体广告

AnimeGANv2实战&#xff1a;动漫风格社交媒体广告 1. 引言 随着人工智能技术在图像生成领域的不断突破&#xff0c;将现实世界的照片转化为具有艺术风格的数字作品已成为可能。其中&#xff0c;AnimeGANv2 作为专为“照片转二次元动漫”设计的轻量级生成对抗网络&#xff08;…

作者头像 李华
网站建设 2026/3/31 22:54:38

AnimeGANv2如何实现美颜效果?人脸优化算法深度解析

AnimeGANv2如何实现美颜效果&#xff1f;人脸优化算法深度解析 1. 技术背景与问题提出 近年来&#xff0c;AI驱动的图像风格迁移技术在艺术化图像生成领域取得了显著进展。其中&#xff0c;将真实人物照片转换为二次元动漫风格的应用场景尤为受欢迎&#xff0c;广泛应用于社交…

作者头像 李华
网站建设 2026/4/12 16:39:41

access数据库损坏后的修复方法

access数据库是微软Office套件里的“轻量级”关系型数据库&#xff0c;特别适合个人或小团队处理结构化数据。它最大的优势是‌零代码上手‌——通过可视化操作就能完成数据管理&#xff0c;同时支持VBA编程实现复杂功能。“轻量级”“关系型”基本上把Access的应用场景和特征说…

作者头像 李华