C++中const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。const最常见用途是作为数组的界和switch分情况标号(也可以用枚举符代替),分类如下:
常变量: const 类型说明符 变量名
常引用: const 类型说明符 &引用名
常对象: 类名 const 对象名
常成员函数: 类名::fun(形参) const
常数组: 类型说明符 const 数组名[大小]
常指针: const 类型说明符* 指针名 ,类型说明符* const 指针名
需要指明的是:const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用。在常变量(const 类型说明符 变量名)、常引用(const 类型说明符 &引用名)、常对象(类名 const 对象名)、 常数组(类型说明符 const 数组名[大小]), const与 “类型说明符”或”类名“(其实类名是一种自定义的类型说明符) 的位置可以互换。如:
const int a=5; 与 int const a=5; 等同
类名 const 对象名 与 const 类名 对象名 等同
一、常量与指针
1 #include <stdio.h> 2 int main() 3 { 4 int k = 100; 5 int q = 256; 6 const int *pa = &k; 7 int *const pb = &k; 8 9 printf("pa = %x *pa = %d | pb = %x *pb = %d ",pa,*pa,pb,*pb); 10 //pa = pb = &k *pa = *pb = 100 11 // *pa = 99; //编译错误 12 *pb = 99; 13 printf("pa = %x *pa = %d | pb = %x *pb = %d ",pa,*pa,pb,*pb); 14 //pa = pb = &k *pa = *pb = 99 15 // pb = &q; //编译错误 16 pa = &q; 17 printf("pa = %x *pa = %d | pb = %x *pb = %d ",pa,*pa,pb,*pb); 18 //pa = &q pb = &k *pa = 256 *pb = 99 19 return 0; 20 }
const修饰指针变量时:
(1)只有一个const,如果const位于*左侧,表示指针所指数据是常量,不能通过解引用修改该数据;指针本身是变量,可以指向其他的内存单元。
(2)只有一个const,如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址;指针所指的数据可以通过解引用修改。
(3)两个const,*左右各一个,表示指针和指针所指数据都不能修改。
二、常量与引用
常量与引用的关系稍微简单一点。因为引用就是一个变量的别名,它本身就是一个常量。也就是说不能再让一个引用成为另外一个变量的别名, 那么他们只剩下代表的内存区域是否可变。即:
1 int i = 10; 2 const int& ri = i;// 正确:表示不能通过该引用去修改对应的内存的内容。 3 int& const rci = i;// 错误!不能这样写。
由此可见,如果我们不希望函数的调用者改变参数的值。最可靠的方法应该是使用引用。下面的操作会存在编译错误:
1 void func(const int& i) 2 { 3 i = 100;// 编译错误!不能通过i去改变它所代表的内存区域。 4 } 5 int main() 6 { 7 int i = 10; 8 func(i); 9 return 0; 10 }
三、常量函数
(1)const修饰的成员函数不能修改除mutable修饰的变量之外任何的成员变量
(2)const成员函数不能调用非onst成员函数,因为非const成员函数可以会修改成员变量
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 5 class Point{ 6 public : 7 Point(int _x,int _y):x(_x),y(_y){} 8 void testConstFunction(int _x,int _y) const 9 { 10 // x=_x;//编译错误,在const成员函数中,不能修改任何类成员变量 11 // modify_x(_x);//编译错误,const成员函数不能调用非const成员函数,因为非const成员函数可以会修改成员变量 12 y = _y; 13 } 14 void modify_x(int _x){ 15 x=_x; 16 } 17 int x; 18 mutable int y; 19 }; 20 21 int main() 22 { 23 Point pt(3,5); 24 printf("x = %d y = %d ",pt.x,pt.y);//x = 3 y = 5 25 pt.testConstFunction(5,7); 26 printf("x = %d y = %d ",pt.x,pt.y);//x = 3 y = 7 27 return 0; 28 }
四、常量返回值
很多时候,我们的函数中会返回一个地址或者引用。调用这得到这个返回的地址或者引用后就可以修改所指向或者代表的对象。这个时候如果我们不希望这个函数的调用这修改这个返回的内容,就应该返回一个常量。即:
1 const int ff(); //返回的是常量,所以必须这么调用 const int a=ff()