美文网首页
处理类型

处理类型

作者: Troll__Zhao | 来源:发表于2016-01-22 13:02 被阅读0次

随着程序的越来越复杂,程序中用到的类型也越来越复杂,体现在两个方面:

  • 类型名称难于拼写,名字既难记由容易写错,还无法确定其真实目的是什么
  • 有时候根本不知道所需要的类型是什么,我们必须从上下文寻求帮助

这时候我们主要有三种解决方案:

  1. 类型别名
    类型别名是一个名字,是某种类型的一个同义词。
    传统方法定义别名用的是typedef
typedef double wages;      //wages是double的同义词
wages hourly, weekly;       //等同于double hourly, weekly;

C++11标准规定了一种新的办法,即使用别名声明,using:

using wages = double;    //wages是double的同义词
wages hourly, weekly;     //等同于double hourly, weekly;

这里需要注意的是,假如某个类型别名指代的是复合类型或者常量,那么把它用到声明语句里就会产生意想不到的后果:

typedef char *pstring;
const pstring cstr = 0;    //cstr指向char的常量指针
const pstring *ps;          //ps是一个指针,它的对象是指向char的常量指针

这里必须要明白,pstring实际上是指向char的指针,所以const pstring就是指向char的常量指针,而非指向常量字符的指针,不能简单的将类型别名替换成他本来的样子

const char *cstr = 0;     //这是对const pstring cstr的错误理解

2.auto类型说明符
在我们编程的时候,常常需要把表达式的值赋值给变量,这要求在声明变量的时候知道表达式的类型,然而这一点是很不容易的,所以C++11引入了auto说明符来帮助我们推断表达式所属的类型,由auto的特性我们知道,auto定义的变量必须有初始值。
这里我们要注意的是,auto可以在同一条语句中声明多个变量,但是一条语句中只能有一个基本数据类型,所以该语句中所有的初始基本数据类型都必须一样

auto i = 0, *p = &i;        //正确,i是整型,p是整型指针
auto sz = 0, pi = 3.14   //错误,sz是整型, pi是浮点型

使用auto我们还必须要注意以下几点:

  • 首先,和我们之前所知道的一样,使用引用其实就是使用引用的对象,特别的是,当引用作为初始值的时候,参与初始化的实际上是引用的对象的值。所以,编译器此时以引用对象的类型作为auto的类型:
int i = 0, &r = i;
auto a = r;               //a是int型(r是i的别名,而i是int型)
  • 其次,auto一般会忽略顶层const,同时底层const会被保留下来:
const int ci = i, &cr = ci;
auto b = ci;                      //b是int型(ci的顶层const被忽略)
auto c = cr;                      //c是int型(cr是ci的别名,ci的顶层const被忽略)
auto d = &i;                      //d是指向int型的指针
auto e = &ci;                     //e是指向int型常量的指针
  • 如果希望推断出来的是一个顶层const,需要明确的指出:
const auto f = ci;      //ci的推演类型是int,而f是const int
  • 还可以将引用的类型设置为auto,此时原来的初始化规则仍然适用:
auto &g = ci;             //g是一个整型常量引用,绑定到ci
auto &h = 42;            //错误,非常量引用不可绑定字面值
const auto &j = 42;   //正确,常量引用绑定字面值

设置一个auto的引用的时候,初始值中的顶层常量属性仍然保留

  • 要在一条语句中定义多个变量,切记,符号&和*只从属于某个声明符,而非基本数据类型的一部分,因此初始值必须是同一种类型:
auto k = ci, &l = i;         //k是int型, l是int型引用
auto &m = ci, *p = &ci;  //m是int型常量引用,p是指向int型常量的指针
auto &n = i, *p2 = &ci    //错误,n是int型引用,而p2必须是指向int型常量的指针,这里确实指向int型的普通指针

3.decltype类型指示符
有时候会碰到这样的情况,我们想用某个表达式的类型定义某个变量,但是不想用该表达式的值初始化这个变量。C++11给我们提供了decltype说明符,它的作用是返回操作数的数据类型。
decltype处理底层const和引用的方式与auto不同。如果decltype使用的表达式是一个变量,那么decltype返回该变量的类型(包括顶层const和引用在内)

const int ci = 0, &cj = ci;
decltype(ci) x = 0;            //x的类型是const int
decltype(cj) y = x;             //y的类型是const int &
decltype(cj) z;                  //错误,z的类型是const int &,必须初始化

下面让我们看一组有趣的情况:

int i = 42, *p = &i, &r = i;
decltype(r + 0) b;
decltype(*p) c

在上述的代码中,decltype(r + 0)返回的类型是int型,这是因为,r作为表达式的一部分,r + 0实际上参与运算的是i + 0,返回的是一个具体的值,而非引用,是int型,但是decltype(r)返回的类型是int &,这点需要明白。

最后一点需要懂得的是,如果decltype使用的是一个不加括号的变量,那么得到的结果是这个变量的类型,一旦加上括号,得到的是引用类型

decltype((i)) d;    //错误,d是一个int &,必须初始化
decltype(i)  e;     //正确,e是一个为初始化的int型变量

相关文章

  • 处理类型

    随着程序的越来越复杂,程序中用到的类型也越来越复杂,体现在两个方面: 类型名称难于拼写,名字既难记由容易写错,还无...

  • webpack打包配置-3-loader的使用

    注意:webpack默认只能打包处理JS类型的文件,无法处理非JS类型文件 如果要处理 非JS类型文件,需手动安装...

  • 污泥处理类型

    污泥消化(sludge digestion):在氧或无氧的条件下,利用微生物的作用,使污泥中的有机物转化为较稳定物...

  • vue 处理后台返回的long类型数据

    js处理long类型的时候数据会丢失精度。 解决方法大体就是后端使用string类型 或者前端对long类型做处理...

  • Android NDK开发之旅23--C++--异常处理

    异常处理 与Java类似,C++也有异常处理。 异常类型 C++中,异常的类型是任意的,如下: throw不同类型...

  • Kotlin 中创建对象

    集合类型都这么处理 , 普通类型就null表示没有。

  • 第十二章:异常处理

    异常处理语法格式: try: ...处理语句 except 异常类型: ...异常处理语句 pytho...

  • Android AsyncTask的用法

    AsyncTask ·Params为传入参数类型 ·Progress为处理参数类型 ·Result为返回类型 例如...

  • MySQL存储引擎:MyISAM和InnoDB区别详解

    它们基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性...

  • mysql中innodb和myisam的区别

    MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。 MyISAM类型的表强调的是性能,其执行数度比...

网友评论

      本文标题:处理类型

      本文链接:https://www.haomeiwen.com/subject/bctrkttx.html