企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
# 1.5、类型处理 ## 类型别名 C++ 提供两种定义类型别名的方式:`typedef` 和 `using`,其中使用 `using` 定义类型别名为 C++11 标准。 ``` c++ typedef type newname; using newname = type; ``` **define 和 typedef的区别** `typedef` 和 `#define` 都是替一个对象取一个别名,来增强程序的可读性,但是它们有以下几个区别: 1. 原理不同:`#define` 是 C 中的语法,它是预处理指令在预处理的时候进行 简单的字符串替换,不作任何的正确性的检查,只有在编译期才能发现错误;而 `typedef` 是关键字,在编译的时候处理,所以 `typedef` 是有类型检查的功能,在作用域内给类型定一个别名。 2. 功能不同:`typedef` 用来定义类型的别名;`#define` 不只是可以为类型取别名,还可以定义常量、变量、函数、代码。 3. 作用域不同:`#define` 是没有作用域的;而 `typedef` 是带作用域的。 4. 对指针的操作不同: ``` c++ #define INTP1 int* typedef int* INTP2; INTP1 p1, p2; // 宏展开之后编程 int* p1, p2; p1 为指针,p2为整型 INTP2 p3, p4; // p3,p4均为指针 ``` ## 类型转换 **C 风格的类型转换**:`Type b = (Type)a`,无条件转换。 **C++的四种类型转换**: * `const_cast`: 去除变量的const属性,`type p = const_cast<type>(q);`; * `static_cast`:类似于C风格的强制转换,无条件转换,`type p = static_cast<type>(q);`; * `dynamic_cast`:有条件转换,动态类型转换,运行时类型安全检查,`type p = dynamic_cast<type>(q);`; * `reinterpret_cast`:仅仅重新解释类型,但没有进行二进制的转换; **内置类型的值转化** * 非布尔型到布尔型:只有值为0是为false,其它情况为true; * 布尔型到其它算术类型:只有值为false的时候为0,其它情况为1; * 浮点型到整型:结果将被截断,仅保留小数点前的数值; * 整型到浮点型:小数点后部分为0; * 赋值一个溢出值给无符号整型:仅保留对应无符号整型可接受的 bit 位; * 赋值一个溢出值给有符号整型:无定义行为; ## 类型推导 在C++11标准下,可以使用 `auto` 和 `decltype` 两个关键词进行类型的自动推导。 ### auto 通过 `auto` 可以让编译器自行计算变量的类型(在编译阶段确定): ``` c++ int i = 0, *p = &i; auto ai = i; // ai is an int auto ap = p; // ap is a pointer to int ``` 在某些情况下 `auto` 计算的得到的类型不和初始类型保持一致: 1、对于引用对象, `auto` 会识别其对应的类型,而不是该引用。 ``` c++ int i = 0, &r = i; auto a = r; // a is an int (r is an alias for i, which has type int) ``` 2、`auto` 通常会忽略 top-level const属性。 ``` c++ const int ci = i, &cr = ci; auto b = ci; // b is an int (top-level const is dropped) auto c = cr; // c is an int (cr is an alias for ci whose const is top-level) auto d = &i; // d is an int* auto e = &ci; // e is const int* (& of a const object is low-level const) const auto f = ci; // deduced type of ci is int; f has type const int ``` ### decltype `decltype` 支持从表达式中推导类型,并且保留 const 和引用等属性。 ``` c++ decltype(f()) sum = x; // sum has whatever type f returns, the compiler does not call f ``` ### auto 和 decltype 的区别 * auto 要求变量必须初始化,也就是在定义变量的同时必须给它赋值;而 decltype 不要求,初始化与否都不影响变量的类型; * decltype 会保留 const 限定符,而 auto 有可能会去掉 const 限定符; * decltype 会保留引用类型,而 auto 会抛弃引用类型,直接推导出它的原始类型;