Const的使用

C语言中一般使用#define来定义常量,而C++中推荐使用const。因为#define定义的常量只是定义了名字和值的映射,存储在符号表中,在预处理阶段进行名值替换,不会进行类型检查操作。而const会进行类型检查。

c++中const默认是内部链接的,也就说,const仅在const被定义过的文件里才是可见的,而在链接中不能被其他编译单元看到。这是因为const默认也是放到符号表中的,不会为其分配内存空间。但也有例外:当使用extern和取const变量的地址时,会强制为其分配内存空间。e.g. extern const int size=10; 或 const int size=10; const int * p=&size。都会分配空间。

如果在一个文件中如此定义:extern const int size=10;而另一个文件中有:extern const int size;那么第一个是定义,而第二个是声明。它们指的是同一个size。也就是说,extern使const变为了外部链接。

const的使用已经渗透到了C++的很多方面:

const int a[]={1,2,3};这里必须初始化。const int a[3];是错误的。

const int * p;这里不需要初始化。自己想想为什么?另一种形式:int const * p;

int a; int * const p=&a;这里必须初始化。

const int* const p=&a;

此外字符串是常量的。所以对一个字符串的修改会出错。

char* p="freewater";

*p='a';//error!

不过我们可以使用字符数组:

char str[]="freewater";

*str='a';//ok

函数参数和返回值

返回const值

const 修饰函数参数表明函数中该参数是不可变的。而修饰返回值,对对于内部类型来说,按值返回的是否是一个const,是无关紧要的,因为返回值本身就是一个变量的副本,所以按值返回一个内部类型时,应该去掉const。当处理用户定义的类型时,按值返回常量是很重要的,表明该函数的返回值不能作为赋值号=的左值。

临时变量

有时候,在表达式求值过程中必须创建临时变量。临时变量自动成为常量。编译器使得所有的临时变量自动成为const。

类里的const

在一个类里放一个const值意味着:在这个对象的生命周期内,它是一个常量。然而,对这个变量来讲,每个不同的对象可以含有一个不同的值。且这个const值必须通过构造函数初始化列表初始化。因为这个常量会被分配空间,因此不能为静态分配数组时使用的长度。

但是如果使用static const就可以生成一个编译期间的常量。e.g.

class T{

static const int size=100;

int a[size];//ok

};

旧版本的c++中,不支持在类中使用static const。可以使用enum替换。

class T{

enum {size=1000};

int a[size];//ok

};

const 成员函数

如果声明一个成员函数为const,则等于告诉编译器该成员函数可以为一个const对象所调用。一个没有被明确声明为const的成员函数被看成是将要修改对象中数据成员的函数,而且编译器不允许它为一个const对象所调用。也就说,const对象既可以调用const成员函数,也可以调用非const成员函数。而非const对象只能调用非const成员函数。

仅仅声明一个函数在类定义里是const是不够的,编译器强迫程序员在定义函数时要重申const的说明。(const已成为函数标示符中的一部分,所以编译器和连接器都要检查const。)

const成员函数是不能对成员变量进行修改的。但是仍然可以通过强制类型转换来突破这种限制。

class Y{
int i;
public:
Y();
void f() const;
};

Y::Y(){i=0;}

void Y::f()const{
//i++;//error
((Y*)this)->i++;//ok,but not recommend
const_cast<Y*>(this)->i++;//recommend

此外,C++中特别提供一个关键字mutable,来支持在const成员函数中修改成员变量。只需使用mutable来定义
成员变量即可。

class Y{
mutable int i;
public:
Y();
void f() const;
};

Y::Y(){i=0;}

void Y::f()const{
i++;//ok and simple
}
原文地址:https://www.cnblogs.com/freewater/p/2614866.html