关键字const能将对象、函数参数、返回值及成员函数定义为常量,并能消除预处理器的值替代而不对预处理器有任何影响。
下面是关于const的几个用法:
一、关于值替代:
1、c++中的const默认为内部连接。一般情况下,c++不为const分配存储空间,相反它把这个定义保存在它的符号表里。当const被使用时,它在编译时会进程常量折叠。
2、const可以用于集合,但编译器不能把一个集合存放在它的符号表里,所以必须分配内存。在这种情况下,const意味着“不能改变的一块存储”。但是,其值在编译时不能被使用。如以下代码:
const int i[] = {1,2,3,4};
float f[i[3]]; //编译器报错
struct s {int i,j;};
const s S[] = {{1,2},{3,4}};
double d[S[1],j]; //编译器报错
二、关于指针
1、指向const的指针
const int* x;
这代表的是:“x是一个指针,它指向一个const int。”这里不需要初始化,因为x可以指向任何东西,但它所指的东西不能被改变。
2、const指针
int d = 1;
int* const x = &d;
这代表的是:“x是一个指针,这个指针是指向int的const指针”。现在指针本身是const指针,编译器要求给它一个初始化值,这个值在指针寿命期间不变。但是要改变它所指向的值是可以的,例如可以写*x = 2;
3、还可以写成把一个const指针变为一个const对象:
int d = 1;
const int* const x = &d;
这样,指针和对象都不能改变。
4、我们可以把一个非const对象的地址赋给一个const指针,但是不能把一个const对象的地址赋给一个非const指针。当然,能用类型转换强制进行这样的赋值,但这是一个不好的习惯
int d = 1;
const int e = 2;
int* u = &d; //正确,d是一个非const对象
int* v = &e; //错误,e是一个const对象
int* w = (int*)&e; //正确,但这是一个不好的习惯
三、类成员函数中const的使用
一般放在函数体后,如:void fun()const;
如果一个成员函数不会修改数据成员,最好将其声明为const,因为const成员函数中不允许对数据成员进行修改,如果修改,编译器将报错,这打打提高了程序的健壮性。
假如我们想要建立一个const成员函数,但是仍然想对对象里改变某些数据,有两种方法:一种称为强制转换const,取this并把它强制转换成指向当前类型对象的指针;另一种是在类声明里使用关键字mutable,以指定一个特定的数据成员可以在一个const对象里被改变。如下面的代码:
#include "ff.h"
#include "dd.h"
#include <string.h>
#include <iostream>
using namespace std;
class fred
{
public:
int i;
mutable int j;
int f()const;
};
int fred::f()const
{
((fred*)this)->i++;
j++;
return i;
}
int main()
{
return 0;
}