C++ Primer读书笔记第二章⑤
C++ Primer
第二章 变量和基本类型
类型别名
我们要给类型取个另外的名字,为什么这么干呢?大概是怕有些类型太复杂了,反正我还没碰到过要用类型别名的,大家看到能理解就好。
typedef double wages; //wages和double一样
typedef wages base, *p; //base=double, p=*double
新标准又搞了个差不多的
using Si = int; //SI和int一样
Si a = 1; //等价于int a = 1;
==既然有了个新东西,那指针又要来搞事情了==
typedef char *x;
const x cstr1 = 0;
const char *cstr2 = 0;
这里的两个cstr一样吗? 不一样:cstr1是指向char的常量指针,cstr2是指向const char的指针,所以,不能直接用char 来代替x,怎么理解呢? 当我们typedef了x之后,x的含义虽然是char ,但x本身已经作为一个基本数据类型无法分割了,所以const x cstr1这句话理解的时候,应该把x当成int之类的来理解,这样const就是顶层的,说明它本身是常量,所以cstr1是个常量指针,指向char。 再来个稍微复杂的
const x *ps;
ps是一个指针,它指向的对象是:指向char的常量指针。
auto类型说明符(万能)
auto a = b; //在不清楚b是什么类型的情况下,用auto,编译器会帮我们分析b的类型
这个auto是不是超级好用,什么都可以装,于是,下面看看它带来的麻烦: 编译器推断出的auto类型有时候和初始值的类型并不完全一样
int i = 0;
int &r = i;
auto a = r; //a是int
//注意,auto一般会忽略顶层const,但保留底层const,
//也就是说忽略本身是常量,保留所指的是常量
const int ci = i; //顶层const
const int &cr = ci; //底层const
auto b =ci; //b是int,忽略了顶层const
auto c = cr; //c是int,虽然cr是底层const,但cr只是ci的别名,ci本身是顶层const
auto d = &i; //d是整型指针
auto e = &ci; //对对象取地址是底层const,所以e是指向整型常量的指针
如果强行希望推断出的auto类型是顶层const,需要明确指出
const auto f = ci; //ci的推断类型是int,但f是const int
看一下引用的情况,设置类型为auto引用时,顶层const仍然保留
auto &g = ci; //g是整型常量引用
auto &h = 42; //错误:42推断出int,等价于 int &h = 42,非常量引用去引用常量,违法
const auto &j = 42; //可以
decltype类型指示符
我们使用auto可以万能,但我们不知道具体是什么类型,比如
auto a = b; //肯定合法,但是你知道a是啥类型吗
于是,C++设计者们又搞了个好东西,函数decltype,它的作用是返回操作数的数据类型
const int ci = 0, &cj = ci;
decltype(ci) x = 0; //x的类型是const int
decltype(cj) y = x; //y的类型是const int &,绑定到x
decltype(cj) z; //错,z是个引用,必须初始化
注意!
引用从来都是作为其所指对象的同义词出现,只有用在decltype处是个例外 再来点复杂的:
int i = 42, *p = &i, &r = i;
decltype(r+1) b; //正确:加法表达式结果为int
decltype(*p) c; //错误:
//表达式的内容是解引用,则函数返回引用,等价于int &c,引用未被初始化
下面是一种神奇的情况:
decltype(i) d; //正确
decltype((i)) e; //错误
//编译器将(i)作为一个表达式处理,返回引用
总结:decltype((i)) 的结果永远是引用,而decltype(i)只有当i本身是引用的时候才是引用。
曼迪匹艾公司福利 146人发布