关于c/c++中const的用法有很多,也十分重要,下面整理一下我学习到的关于const的部分用法,讲的有错的地方请在评论区指正。
1、一般对象的const
一般对象用const修饰的时候,说明这个对象一般不允许被修改。而且需要注意,const修饰变量在定义时必须被初始化(可以用表达式或者函数)。
那么有一个问题,在一个class中,如何用构造函数对const变量进行初始化,答案是使用初始化列表。如下:
class A
{
A(int a,int b):x(a),y(b){}
private:
const int x;
const int y;
};
而在构造函数体内的属于赋值,在没有进行初始化是,会有默认初始化。
这又扯到初始化的问题了,详情请看《Effective C++》条款4。
2、关于引用的const
引用的const需要注意的有以下几点:
一个const变量必须是const的。这点应该比较容易理解,因为如果一个变量定义为const,初衷就是为了不被改变,但你的引用不是const,我就可以通过引用来改变,显然是不可以的。
还有一个比较有趣的地方是如下:
double pi=3.14;
const int &data=pi;
这个代码是合法的,其实编译器做的真正的内容是:
double pi=3.14;
const int temp=pi;
const int &data=temp;
temp在这里被称为临时量,但是上述代码如果改为:
double pi=3.14;
int &data=pi;
则会出现错误。原因我想比较容易理解,此时若给data赋值,则data绑定的其实是临时量,而不是真正的pi。
3、关于指针的const
我觉得指针的const是所有里面最难理解的部分。
这里涉及到顶层const和底层const。
如下:
int data=9;
const int *p1=&data;
int *const p2=&data;
const int *const p3=&data;
里面涉及const的三条语句的含义如下:
第一个:const修饰int,表示data的值不能改变,但是指针的值可以变,也就是指针可以指向其他的变量。
第二个:const修饰指针,表示data的值可以改变,但是指针的值不能改变。需要注意的是,这条语句不能写成*const int p2=&data;
第三个:综合了上述两个。
用《C++primer》的意思来说,顶层const表示指针本身是个常量,而底层const表示指针所指的对象是个常量。但是并不完全如此,如下:
const int data1=42;
在这里的const就是一个顶层const。
在拷贝的时候需要特别注意底层const,拷入拷出的对象必须具有相同的底层const,或者两个对象类型必须能够相互转化(一般为非常量转化为常量)。
这一部分可以和迭代器中的const_iterator一起理解
4、成员函数的const
首先将成员函数,特别是某些运算符重载成const是非常必要的,因为用户作用的对象可能需要满足const的要求。当然在重载同一个函数的const和非const版本时,我们为了避免代码重复,可以使非const函数调用const函数,当然过程中需要用cons_cast和static_cast进行必要的转化。
在成员函数的末尾加const意思为此函数不对变量进行修改,这样做的目的我想应该是为了方便函数调用者更好地理解,当然你可以给变量加mutable来使该成员在const成员函数中能够被修改。
写完发现语言组织能力不是很够,有些东西讲的不是很清楚,还请见谅。