1、默认状态下,const
对象仅在当前文件内有效
默认情况下,const对象被设定为仅在当前文件内有效。当多个文件中出现了同名的const
变量时,等同于在不同文件中分别定义了独立的变量。
解决的办法是,对于const
变量不管是声明还是定义都添加extern
关键字,这样只需在一个文件中定义一次就可以了。
2、对const
的引用
把引用绑定到const
对象上,称之为对常量的引用。
虽然引用不是对象,但是引用有地址,可以用&
获取引用的地址,引用的地址就是绑定到的对象的地址。
普通引用无法绑定到字面值常量,但是对const
的引用就可以绑定到一个字面值常量,而且绑定对象的类型可以和引用的类型不同:
double d = 3.14;
const int& r = d;
这太神奇了!!!那么,这是为什么呢?
其实,r
绑定的是一个临时对象,编译器把上述的第二条语句改成了如下形式:
const int temp = d; 由double生成一个临时的const int
const int& r = temp; r 绑定到这个临时量
3、指针和const
只有把 *
放在const
关键字前面用来说明指针是一个常量。
当你把*
放在const
后面时, const
修饰的就不是*
(指针)了,所以也就不是指针常量了。
那,把*
放在const
后面时,const
到底修饰谁?他总要起作用吧。
我自己总结了下面这样的规律:
- ① 当
const
出现在第一个位置时,他修饰的就是它后面出现的第一个标识符。 - ② 当
const
不在第一个位置时,他修饰的是它前面出现的第一个标识符。
以下面的声明为例:
char const * p1;
const char const * p2; 这两条声明其实是等价的
p1
和 p2
的类型其实是一样的。
p1
的声明中,const
修饰它前面的标识符,也就是char
,所以p1
是const char*
类型,是个指向常量的指针
p2
的声明中,第一个const
修饰它后面的char
,而第二个const
也修饰char
。所以第二个const
其实是多余的,不写也没关系,但即使他是多余的,她也不会去修饰后面的*
。所以p2
也是const char*
类型,也是指向常量的指针。
再举一个例子:
char* const p3; 错误,没提供初始值
const char* const p4; 错误,没提供初始值
这两条语句其实都不能通过编译。因为p3
,p4
都是const
指针,必须为其提供初始值才行,不过这不影响我们分析它们的类型。
p3
的声明中,const
修饰它前面的*
,所以p3
是个指针常量,指向char
类型。
p4
的声明中,第一个const
修饰char
,第二个const
修饰*
,所以p4
也是个指针常量,指向const char
类型。
因为两个指针都是常量,所以初始化的时候必须给出他们的明确指向。