跳至主要內容

06. 其他类型

LincZero大约 4 分钟

06. 其他类型

复合类型 > 类型模板类 > 共用体 union

简概

  • 说明:能存储不同的数据类型,但只能同时存储其中的一种类型

  • 共用体与结构的区别:语法相似但含义不同

    比方说,前者可以同时存储int、long、double,后者只能存储int、long、double中的其中一种

  • 注意项:需要有足够的空间来存储最大的成员

  • 使用场景:当数据项使用两种或更多格式(但不会同时使用)时,可节省空间

使用

字面量方式

  • 类型定义:例union one4all{int i_val; long l_val; double d_val;}

  • 类型定义 - 匿名共用体:没有名称,成员将成为位于相同地址处的变量(每次只有一个成员是当前成员)

    struct widget{union{ long l_val; char arc_val[20]; }}; widget prize.l_val = 12;

  • 声明:例one4all pail

  • 赋值:例pail.i_val = 26pail.d_val = 1.38会覆盖前一个

复合类型 > 类型模板类 > 枚举 enum

简概

  • 作用:创建符号常量,可以代替const,
  • 使用上:与结构体相似
  • 运算:没有未枚举定义算术运算,不能进行此类操作
  • 使用场景:可以配合switch-case使用,或者使用匿名枚举创建符号常量
  • 技巧:匿名枚举
    • 与结构体不同的是,可以将枚举的使用拆成两部分:定义符号常量(枚举量)和定义枚举变量,而后者并不是必须的

使用

字面量方式

  • 类型定义:例enum spectrum {red, orange, yellow}

    • 枚举量:其中red、orange、yellow等作为符号常量,对应整数值0~2,这些常量叫作枚举量

    • 枚举量的值:可以设置枚举的值,如enum bits {one=1, two=2, four=4, eight=8}

      枚举量的值可以相同,如enum {zero, null=0}

    • 匿名枚举:如果只打算使用常量而不创建枚举类型的变量,则可以省略枚举类型的名称

  • 声明:例spectrum band;

  • 赋值:只能将定义枚举时使用的枚举量赋值给这种枚举的变量,如band = red,否则不合法

内置函数方法

  • 类型转换:枚举量可以被提升为int类型,被转换为序列量,但反之不行,除非使用强制类型转换band = spectrum(2)

【缺陷补丁】作用域内枚举(C++11)

  • 问题
    • 两个枚举定义的枚举量可能发生冲突
    • 例如:enum egg {Samll, Medium, Large, Jumbo}; enum t_shirt {Small, Medium, Large, Xlarge};
    • 这将无法通过编译
  • 解决
    • C++11提供了一种新枚举,其枚举作用域为类
  • 使用
    • enum后加上关键字class
    • 定义:enum class egg {Samll, Medium, Large, Jumbo};
    • 调用:egg choice = egg::Large;
  • 补充
    • C++11还提高了作用域枚举的类型安全,如不能隐式地转换为整型

特殊类型 > 自动类型

auto

decltype

关键字decltype(C++11)

  • 作用

    • decltype和auto有异曲同工之妙,均可用来自动判断类型
  • 使用

    • 通用:decltype(expression) var;
    • 举例:decltype(x+y) xpy; xpy=x+y;或者decltype(x+y) xpy = x+y;
  • 使用场景

    • 通常与函数模板结合使用
  • 核对表:decltype(expression) var;

    • expression举例var的类型
      一个没有用括号括起的标识符与该标识符的类型相同
      一个函数调用与返回值类型相同
      一个左值且不为情况一((n))为指向其类型的引用
      前面的条件都不满足比如表达式与expression类型相同

【缺陷补丁】后置返回类型(C++新增语法)

  • 使用

    • 举例:double h(int x, float y);可写成auto h(int x,float y)->doublw

      其中->double被称为后置返回类型trailing return type),其中auto是一个占位符用于表示后置返回类型提供的类型

    • 话说Typescript函数的返回类型就是经典的后置返回类型,原理就不知道是不是一样的了

      // ts函数定义式,返回值写在后面,前面用`:`符号
      function f1(n1:number, n2:number): number{}
      
      // ts函数声明式,返回值也是写在后面,前面用`=>`符号
      export interface i1{
          f2: (n1:number, n2:number)=>number|null
      }
      
  • 使用场景

    • 用于解决decltype本身的一个缺陷。可配合auto、decltype使用
    • 使用decltype有一个缺陷
      • 比如?type? ge(T1 x, T2 y){...return x+y}时无法得知返回的类型
      • 此时不能使用decltype(x+y)作为返回类型,因为此时x和y未声明
      • 于是可以把返回类型移到参数声明的后面
  • auto和decltype区别

    • decltype可用于指定自定义的类型而并非完全是自动类型
    • 但为什么不能用auto代替decltype???新增这个新的关键字有意义吗???