2026/4/8 0:03:36
网站建设
项目流程
网站域名管理权限,可以定制东西的软件,平台公司运营模式,庆阳网站设计一、编译期类型判断#xff08;静态类型检查#xff09;这类判断在编译阶段完成#xff0c;零运行时开销#xff0c;主要用于模板编程、类型萃取等场景。1. typeid 运算符#xff08;基础#xff09;typeid 可以获取类型信息#xff0c;返回 std::type_info 对象#x…一、编译期类型判断静态类型检查这类判断在编译阶段完成零运行时开销主要用于模板编程、类型萃取等场景。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. 模板类型萃取C11 及以上通过标准库的std::is_same、std::is_pointer、std::is_class等模板在编译期精准判断类型属性。代码示例cpp运行#include iostream #include type_traits // 必须包含此头文件 template typename T void check_type(T value) { // 判断是否为指定类型 if constexpr (std::is_same_vT, int) { // C17的is_same_v等价于std::is_sameT, int::value std::cout Type is int std::endl; } else if constexpr (std::is_same_vT, double) { std::cout Type is double std::endl; } // 判断类型属性 std::cout Is pointer: std::boolalpha std::is_pointer_vT std::endl; std::cout Is floating point: std::is_floating_point_vT std::endl; std::cout Is arithmetic: std::is_arithmetic_vT 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_vMyClass std::endl; // true return 0; }关键说明std::is_sameT, U判断 T 和 U 是否是完全相同的类型包括 const/volatile 修饰。if constexprC17编译期条件判断不会为不满足的分支生成代码避免运行时开销。常用类型萃取模板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_castDerived1*(ptr)) { std::cout Object is Derived1 type std::endl; } // 判断是否为Derived2类型 else if (Derived2* d2_ptr dynamic_castDerived2*(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_castDerived1(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; }三、常见使用场景模板编程用std::is_same/std::is_pointer等编译期判断实现类型分支逻辑。多态场景用dynamic_cast判断基类指针 / 引用实际指向的子类类型。类型安全检查避免错误的类型转换如将非多态类强制转换。总结编译期判断用std::is_same/std::is_pointer等模板type_traits零运行时开销适合模板编程。运行期判断仅适用于多态类用dynamic_cast推荐或typeid有轻微运行时开销。核心注意dynamic_cast依赖虚函数表仅对多态类有效typeid对非多态类仅返回编译期类型。