重写c++ primer(6)
const 限定符:
我们希望定义这样一种变量,它的值不能被改变。还有我们有时候要防止改变某一个值。所以为了满足这个要求,我可以用const限定符加以限定。比如:
const int bufsize=512;
这样就把bufsize定义成了一个变量,任何试图为bufsize赋值的行为都将引发错误。如:
bufsize=512;//试图向const对象写值
因为const对象一旦创建后其值就不能改变。所以const对象必须初始化。
const int i=get_size();
const int j=42;
比如以上表达式就是正确的范例,还有:
const int k;
像这样没有给予初始化的表达式往往会导致编译错误。
初始化和const
关于初始化,如果利用一个对象去初始化另外一个对象,则他们是不是const都无关紧要。:
int i=42;
const int ci=i;
int j=ci;
在上述表达式中,i的值被赋值给了ci,ci的值被赋值给了j。可见这与const没有关系。
默认情况下,const对象仅在文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。通常只在一个文件中定义const,而在其他多个文件中声明并使用它。
对于const变量不管是声明还是定义都添加extern关键字。这样只需定义一次就够了。
extern const int bufsize=fun();
extern const int bufsize;
下面是关于const 引用的。
可以把引用绑定到const对象上,就像绑定在其他对象上一样。我们称为对常量的引用。与普通引用不同的是。对常量的引用不能被修改它所绑定的对象。
const int ci=1024;
const int &rl=ci;//引用及其对象都是常量。
rl=42;//错误,rl是对常量的引用。
int &rl=ci;//试图让一个非常量引用指向一个常量引用。
初始化和对const的引用
引用的类型必须与其所引用的对象的类型一致。但有两个情况。第一,在初始化常量引用时,容许用任意表达式作为初值,只要改表达式的结果能转换成引用类型即可。容许为一个常量引用绑定一个非常量对象,字面值。
int i=42;
const int &rl=i;
const int &r2=42;
const int &r3=rl*2;
rl和r3都是引用常量。
对于const的引用可能引用一个并非const的对象,常量引用仅对引用可参与的操作做出了限定,对于引用的对象本身是一个常量未做限定。因为对象可能是一个非常量。所以可以通过其他途径改变。
int i=42;
int &rl=i;
const int &r2=i;
rl=0;
指针与const
与引用一样,也 可以令指针指向常量或非常量。类似于常量引用,指向指针常量的指针不能用于改变其所指对象。要想存放对象的地址,只能使用指向指针常量的指针。
const指针
指针是对象而引用不是,容许把指针本身定义为常量。常量指针必须初始化。而且一旦初始化完成,则它的值就不能被改变了、比如:
int errnumb=0;
int *const curerr=&errnumb;
const double pl=3.14;
const double *const pip=π
指针本身是一个常量并不意味着不能通过指针修改其所指的值。能否这样做依赖于所指对象的类型。
简单总结一下顶层和底层const。
顶层const是指指针本身是一个常量。而底层const是指指针所指对象是一个常量。
当执行拷贝时并不会改变被拷贝对象的值。顶层const不受影响。另外底层const限制不能忽视。当执行拷贝时。拷入和烤出的对象必须为相同的底层const'资格。或者两个对象的数据类型能转换。通常,非常量可以换为常量。反之不行。