news 2026/5/5 2:07:47

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/30 12:54:10

go语言对phone脱敏显示

在Go语言中实现手机号脱敏显示主要有以下几种方式&#xff0c;从简单到完整逐步推荐&#xff1a; 一、基础实现&#xff08;字符串切片&#xff09; 最常用且高效的方式是直接使用字符串切片操作&#xff0c;保留前3位和后4位&#xff0c;中间用*替换&#xff1a; go 复制 …

作者头像 李华
网站建设 2026/5/2 13:37:22

开源模型新选择:AnimeGANv2宫崎骏风格迁移实战指南

开源模型新选择&#xff1a;AnimeGANv2宫崎骏风格迁移实战指南 1. 引言 随着深度学习在图像生成领域的持续突破&#xff0c;风格迁移技术已从实验室走向大众应用。其中&#xff0c;AnimeGANv2 作为轻量级、高效率的动漫风格迁移模型&#xff0c;凭借其出色的画质表现和极低的…

作者头像 李华
网站建设 2026/5/4 23:56:00

Windows 10/11 优化大师 Windows Manager

一、前言&#xff1a;为什么 Windows 10/11 越用越卡&#xff1f; 相信很多朋友都有这样的体验&#xff1a; 新装的 Windows 10 / Windows 11 用着很流畅用了一段时间后&#xff1a; 开机变慢系统反应迟钝后台服务越来越多磁盘空间被莫名其妙占满 即便你不安装乱七八糟的软…

作者头像 李华
网站建设 2026/5/4 21:34:13

VibeThinker-1.5B-WEBUI权限管理:多用户场景下的配置建议

VibeThinker-1.5B-WEBUI权限管理&#xff1a;多用户场景下的配置建议 1. 引言 1.1 业务场景描述 随着轻量级大模型在开发者社区的广泛应用&#xff0c;VibeThinker-1.5B-WEBUI 因其低成本、高推理效率的特点&#xff0c;逐渐成为个人开发者和小型团队进行数学推导与编程辅助…

作者头像 李华
网站建设 2026/5/4 22:50:52

【性能测试】2_JMeter _JMeter文件目录

文章目录一、Bin目录二、docs目录三、printable_docs目录四、lib目录一、Bin目录 Bin目录:存放可执行文件和配置文件。 examples&#xff1a;目录下包含Jmeter使用实例ApacheJMeter.jar&#xff1a;JMeter源码包jmeter.bat&#xff1a;windows下启动文件jmeter.sh&#xff1a…

作者头像 李华
网站建设 2026/4/30 0:19:55

计算机毕设 java 基于 java 青少年篮球俱乐部管理系统设计与实现 基于 Java 的青少年篮球俱乐部管理平台 赛事组织与运动员服务系统

计算机毕设 java 基于 java 青少年篮球俱乐部管理系统设计与实现&#xff08;配套有源码、程序、MySQL 数据库、论文&#xff09;&#xff0c;本套源码可先查看功能演示视频&#xff0c;文末有联系方式可领取。传统青少年篮球俱乐部管理存在赛事信息传递不及时、报名流程繁琐、…

作者头像 李华