const的作用

来源:互联网 发布:nba2k14优化伴侣 编辑:程序博客网 时间:2024/05/17 08:27

常类型也称为const类型,是指使用类型修饰符const说明的类型。constcc++中常见的关键字

c语言中:它主要用于定义变量为常量类型以及修饰函数参数与返回值,而在C++中还可以修饰函数的定义

const的作用

定义const常量,具有不可变性。例如:

const int MAX = 100;

int Array[MAX];

(2) 进行类型检查,使编译器对处理内容有更多的了解,消除了一些隐患,例如:

void f(const int i) { ...}编译器知道i是一个常量,不允许修改。

(3) 避免意义模糊的数字出现,同样可以很方便的进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变。如(1)中如果修改MAX的内容,只需要定义const int

MAX=期望值 即可。

(4)保护被修饰的东西,防止被以外修改,增强了程序的健壮性。

voidconst int i) {

  i = 10// 编译器会报错

}

(5)为函数重载提供参考

class A {

void f(int i) {...} //定义一个函数

void f(inr i) const {...} // 上一个函数的重载

}

(6)节省空间,避免不必要的内存分配。例如:

#define PI 3.14159      // 该宏来定义常量

const int pi = 3.1415926; // 此时并未将 pi 放入只读存储器中

double i=pi// 此时为 pi 分配内存,以后不再分配

double I = PI // 编译期间进行宏替换,分配内存

double j = pi // 没有分配内存

double J = PI // 再次进行宏替换,又一次分配内存

const 定义常量从汇编的角度来看,只是给出了相应的内存地址,而不是像#define一样给出的是立即数,所以const定义的常量在程序运行过程中只有一份复制品,而#define定义的常量在内存中有若干各复制品。

(7)为了提高程序的效率。编译器通常不为普通的const常量分配存储空间,而是将他们保存在符号表中,这使得它成为一个编译期间常量,没有了存储与内存的操作,使得它的效率也很高。

引申1:什么情况下需要使用const关键字?

(1)修饰一般常量。

(2)修饰常数组。定义或说明一个常数组可以采用如下格式:

int const a[8] = {1, 2, 3, 4, 5, 6, 7, 8}

const int a[8] = {1, 2, 3, 4, 5, 6, 7, 8}

(3)修饰常量对象。常量对象是指对象常量

class A;

const A a

A const a;

定义常量对象时,同样要进行初始化,并且该对象不能再被更新。

(4)修饰指针常量

const int* A; // const 修饰指向的对象, A可变,A指向的对象不可变。

int const *A // cconst修饰指向对的对象, A可变,A指向的对象不可变

int* const A// 修饰指针A, A不可变, A指向的对象可变。

const int* const A; // 指针AA指向的对象都不可变

(5) 修饰常引用。使用 const 修饰符也可以说明引用,被说明的引用为常引用,该引用所引用的对象不能被更新。其定义格式如下:

const double &v

(6)修饰函数的常参数const 修饰符也可以修饰函数的传递参数,告诉编译器此参数在函数体内无法改变,从而防止了使用者一些无意或错误的修改。

(7)修饰函数的返回值。例如

函数返回值为 const  只有用在函数返回为引用的情况。函数返回值引用常量表示不能将函数调用表达式作为左值使用。例如前面讲的返回引用的函数int  & min ( int  &i,  int  &j);  可以对函数调用进行赋值,因为它返回的是左值:  min ( a ,  b )=4;但是,如果对函数的返回值限定为 const  的:const  int  & min ( int & i, int  &j );那么,就不能对 min ( a, b ) 调用进行赋值了。

(8)修饰类的成员函数。Const修饰符也可以修饰类的成员函数,格式如下:

class ClassName {

public:

int fun () const;

}这样在函数fun中不能修改类或对象的属性

(9)在另一连接文件中引用const常量。使用方式必须使用extern关键字

extern const int i; // 正确

extern const int j = 10; // 错误,常量不可以被再次赋值。另外还要注意常量必须初始化。

引申2:什么是常引用?

常引用也称之为const引用。之所以引入常引用,是为了避免在使用引用变量时无意修改了变量的值,从而引起程序的错误,常引用主要用于定义一个普通变量的只读属性的别名。

常引用的用途:

(1)用作普通变量的只读属性的别名。通常这个别名只能获得这个变量的值,不能修改这个变量的值。

(2)用于函数的形参。常引用被用作形参,可以确保在函数内不会改变实参的值,所以参数传递时尽量使用常引用类型。

关于引用的初始化,一般要注意以下问题:

当初始化值是一个左值(可以取得地址时,没有任何问题)

而当初始化值不是一个左值时,则只能对一个常引用赋值,而且这个赋值是有一个过程的,首先将值隐示转换到类型T,然后将这个转换结果存放在一个临时对象里,最后用这个临时对象来初始化这个引用变量。

例如如下两种使用方式:

(1)double& dr = 1;

(2)const double& cdr = 1;

第(1)种方法错误,初始化值不是左值,而第(2)种方法正确,其对应的的执行过程如下:

double tmp = double(1);

const double& cdr = tmp;

如果对第(1)种使用方法进行相应的改造,也可以变为合法,例如:

const int ival = 1024;

(1)const int &refVal = itval;

(2)int &ref2 = ival;

(1):合法

(2):非法

原因:因为itval为const常量而ref2并没有申明为常引用。

在使用const引用进行函数调用的时候,需要注意一个问题,

例如如下函数申明:

void bar(string& s);

那么下面的表达式将是非法的。

bar(”hello world“);

原因在 "hello world" 串会产生一个临时对象,而在c++中,临时对象是 const 类型的

因此上面的表达式就是试图将一个const类型的对象转换为非const的类型,这是非法的。引用型参数应该在能被定义为const的情况下,尽量定义为const。