临时记录-C++常量相关
对const无论声明还是定义都使用extern,就能实现常量在多个文件中共享。
比如在其中一个源文件定义,在公共头文件声明。有值的地方就是定义的地方,但是都有extern。
对常量的引用也必须有const的常量引用才能接收绑定(也就是说,必须要常量引用来引用常量)
指向常量的引用(包含const的引用),也可以引用一个普通变量、表达式,甚至值。其作用是,对所引用对象操作做了限制(不允许通过此引用改动),但是还是能够通过其它途径改变的。
const int v;
const int &rv=v;
以上,v是常量,而rv是常量引用。
说法上,有:对常量的引用/常量引用、常量
C++中常量引用可以被字面值初始化,但是普通引用不能。
类似指向常量的引用,也有指向常量的指针。对常量,必须用指向常量的指针来指向常量,同样指向常量的指针指向普通变量限定的只是通过该指针不能修改对应的变量。
const int v;//常量
const int *p = &v;// *指向常量的指针*
int *const pc = &v;//报错,此处是 *常量指针* ,因为pc本身所指地址不能变,但是所指地址值可变,而这里所指地址值是一个const常量。
const int *const pcc =&v;//指向常量的常量指针,前面const表示指针自认为所指为“常量”(不能通过自己改变其值),后面的表示指针本身所指不能改变。
以上,v是常量,p是指向常量的指针(底层const,即间接地p地址值所指值不可变,但p本身值即所指地址可变,)。pc是常量指针(顶层const,即直接p本身值即所指地址就不可变了,但p地址值所指值可变)。
说法上,有:指向顶层常量属性、底层常量属性、常量的指针(只能是常量指针)、常量指针(指针本身值不能变指针可变但指针不改变所指值)、常量。其中,常量指针是因为指针本身是一个对象,所以可以做为常量存在。其中,常量指针是顶层常量属性,指向常量的指针是底层常量属性。
初始化常量时的表达式,并不一定是常量表达式(可能在运行才能确定)。constexpr类型的变量,一定是常量,并且必须用常量表达式初始化,并且在编译期间就能确定变量值。
constexpr类型的一般都是字面值类型,一般就是能用表达式表达的内部类型,而一般自定义类型都无法用一个表达式表达出来。另外,指针和引用如果是constexpr,则必须指向固定的区域,而比如函数内部临时变量就不固定所以不行。
如果constexpr定义指针,那么限定符constexpr仅对指针有效而非指向的对象, 即:指针是常量指针。而非如同const定义的那样指向常量的指针。
<span class="timestamp-wrapper"><span class="timestamp"><2019-11-05 二 10:10></span></span>2.5.1 关于类型别名
类型别名两种方式:typedef, using
对常量修饰别名,需要注意,别名做为一个整体,而非简单替换了。比如:
typedef char * pstr;
const pstr p;// 首先类型是“指针”这个整体,然后const 相当于直接修饰了p, p成了常量,所以 应该是常量指针,而非替换形成的:const char* p这样的指向常量的指针。
const *pstr pp;//首先,pstr是“指针”这个整体,然后const *修饰使得pp它成为指向常量的指针,而若常量为pstr类型,那就是常量指针,所以pp是一个指向常量指针的指针。
<span class="timestamp-wrapper"><span class="timestamp"><2019-11-05 二 11:05> </span></span> 2.5.2关于auto
auto类型,是C++11新标准,该类型变量必须初始化,根据初始化值来推断变量的真正值。形式如:auto val=xxx;
auto用一条语句声明多个变量时,这些变量的初始值类型必须一致(甚至不能多出顶层const属性)。
auto声明时会去掉顶层const属性,但是保留底层const属性。
auto的引用auto&,则保留顶层const属性。
<span class="timestamp-wrapper"><span class="timestamp"><2019-11-05 二 11:07> </span></span> 2.5.3关于decltype
decltype也是C++新标准,传给它一个表达式得出表达式类型(而不是计算这个表达式),
然后用这个类型来声明变量,形式如:decltype(表达式) val; 根据表达式来计算得出val的类型。
如果表达式是变量,类型就是变量类型,如果是用括号扩起来的变量,则类型是一个变量类型的引用。
如果表达式是对指针的解引用,即(*p取值),那么表达式也是引用。
如果表达式是赋值表达式,那么它也会产生引用类型
<span class="timestamp-wrapper"><span class="timestamp"><2019-11-05 二 11:15> </span></span> 2.6 自定义数据结构(未读)
C++11新标准可以设置类内初始值,设置初始值不能用括号,没有初始值将被默认初始化。
<span class="timestamp-wrapper"><span class="timestamp"><2019-11-06 三 10:28> </span></span> 第3章,字符串、向量、数组
头文件中一般不使用using声明
对于string,不能把字面值同时相加,如果相加string,则必须有一个操作数是string类型
为了兼容C,C++包含name.h文件时,也可用cname的方式包含。直接用 cname 包含的会在std命名空间中,而用name.h包含的,则不在std空间中,建议C++中包含c标准库头文件用cname的方式进行。
基于范围的for语句C++11最新引入的语法,形式:
for(declaration:expression)
statement
例如:
for(auto c: str_list)
xxx
如果这里的是引用的 auto &c, 那么会被依次绑定到每个元素。