一直很想把C++相关知识点做一个总结,结果拖到现在,看了博客的记录,上一篇还是两年前写的,真是惭愧。趁着秋招找工作,一次性来个系统总结吧。
const限定符
const关键字用于对变量加以限制,防止修改变量的值。
const int bufSize=512;
此时bufSize是一个常量,此时再对bufSize进行复制会导致错误。因为const对象一旦创建后其值就不能发生改变,因此const还必须得初始化。
const int j=42; //正确,编译时初始化
const int k; //错误,没有初始化
初始化和const
const常量可以和普通变量相互赋值,但是区别是const常量一旦赋值就不能发生改变。
int i=42;
const int ci=i; //正确:i的值拷贝给了ci
int j = ci; //正确:ci的值拷贝给了j
i=32; //正确:i的值可以被修改
const的值一旦被复制,就不能被修改。
const对象仅在文件中有效
当以编译时初始化的方式定义一个const对象时:
const int bufSize = 512;
编译器会在编译过程中将所有用到该变量的代码替换成对应的值。为了执行替换,所以编译器需要提前知道变量的初始值。默认情况下,const对象被设定为仅在文件内有效。当多个文件出现同名const时,相当于在不同的文件定义独立变量。
在多个文件中共享const变量
如果需要在多个文件中共享同一种const变量,并且不希望编译器为每一个文件单独生成变量。这时候就不能再每一个文件中单独定义。具体做法是在一个文件中定义const,在其他文件中申明并且使用它。
//file1.cpp 定义并且初始化一个常量,该常量能够被其他文件访问
extern const int bufSize=512;
//file_1.h 头文件
extern const int bufSize; //与file1.cpp中的bufSize是同一个。
只要在其他文件中导入file1.h的头文件就能够直接使用bufSize
常量引用
使用const修饰的引用不能用于修改它所绑定的对象。并且常量引用能够指向一个非常量对象,而非常量引用不能够指向常量对象。
const int ci=0124;
const int &r1=ci;
r1=42;
int &r2=ci; //错误:非常量引用不能指向常量对象
当常量引用指向非常量对象时,其值是可以改变的,但是却不能通过常量引用改变其值。
int i=42;
const int &a=i;
i++; //此时i变成42,并且对应的a也变成43
a++; //错误,不能通过常量引用改变对象值。
并且我们是不能用常量引用来赋值非常量引用
int i=42;
const int &a=i
int &b=a; //错误
指针和const
指针和引用一样也可以指向常量和非常量。
指针常量
指向常量的指针(pointer to const),国内很多教材翻译成指针常量,不能用于改变其所指向的对象的值。想要存放常量对象的地址,只能使用常量指针:
const double pi=3.14;
double *ptr=π //错误
const double *cptr=&pi //正确
*cptr=42 //错误:不能通过cptr改变指向对象的值
和上面一样,不能通过指针cptr来改变指向的常量对象的值。但是当指向的是一个非常量对象时:
int a=3;
const int *b=a;
a++;
(*b)++ //错误
所以当指向非常量值,可以通过其他方式改变其值,但是不能通过常量指针改变其值。但是指针常量自身的地址却是可以改变的。
int a=3;
const int *b=&a;
int c=4;
b=&c; //此时*b=4
常量指针
指针是对象而引用不是,因此就像其他对象类型一样,可以将指针本身定义为常量。常量指针必须初始化,并且一旦完成初始化,存放在指针中的地址就不能够改变。
int errNumb=0;
int *const curErr=&errNum; //curErr一直指向errNum
const double pi=3.14;
const double * const pip=π //pip是一个指向常量对象的常量指针。
(*curErr)=1;
也就是说curErr里面的的地址不能改变,但是却可以通过指针改变errNumb里面的值,并且curErr的地址也不能够重新赋值。而pip表示的是本身和指向的对象都不能改变。
顶层const
顶层表示指针本身是一个常量,底层表示所指对象是一个常量。其实在前面的时候也涉及到了,下面具体举几个例子:
int i=0;
int *const p1=&i; //不能改变p1的值,这是一个顶层const
int const ci=42; //不能改变ci的值,顶层const
const int *p2=&ci; //允许改变p2的值,指的是p2的地址,底层const
const int *const p3=&ci;//既是一个顶层又是一个底层const
const int *const p4=p2;//右边是一个顶层const,左边是一个底层const