处理类型

2016-01-22  本文已影响0人  Troll__Zhao

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

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

  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我们还必须要注意以下几点:

int i = 0, &r = i;
auto a = r;               //a是int型(r是i的别名,而i是int型)
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 auto f = ci;      //ci的推演类型是int,而f是const int
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型变量
上一篇 下一篇

猜你喜欢

热点阅读