今天来看看const的用法。
第一:常变量
变量用const修饰,其值不得被改变。任何改变此变量的代码都会产生编译错误。Const加在数据类型前后均可。
例如:
void main(void)
{
const int i = 10; //i,j都用作常变量
int const j = 20;
i = 15; //错误,常变量不能改变
j = 25; //错误,常变量不能改变
}
第二:常指针
const跟指针一起使用的时候有两种方法。
const可用来限制指针不可变。也就是说指针指向的内存地址不可变,但可以随意改变该地址指向的内存的内容。
int main(void)
{
int i = 10;
int *const j = &i; //常指针, 指向int型变量
(*j)++; //可以改变变量的内容
j++; //错误,不能改变常指针指向的内存地址
}
const也可用来限制指针指向的内存不可变,但指针指向的内存地址可变。
int main(void)
{
int i = 20;
const int *j = &i; //指针,指向int型常量
//也可以写成int const *j = &i;
j++; //指针指向的内存地址可变
(*j)++; //错误,不能改变内存内容
}
看完上面的两个例子,是不是糊涂了?告诉你一个诀窍,
在第一个例子中,const用来修饰指针j,j不可变(也就是指向int变量的常指针);
第二个例子中,const用来修饰*j,*j不可变(也就是指向int常量的指针)。
这两种方式可以组合起来使用,使指针和内存内容都不可变。
int main(void)
{
int i = 10;
const int *const j = &i; //指向int常量的常指针
j++; //错误,不能改变指针指向的地址
(*j)++; //错误,不能改变常量的值
}
第三:Const和引用
引用实际上就是变量的别名,这里有几条规则:
声明变量时必须初始化
一经初始化,引用不能在指向其它变量。
任何对引用的改变都将改变原变量。
引用和变量本身指向同一内存地址。
下面的例子演示了以上的规则:
void main(void)
{
int i = 10; //i和j是int型变量
int j = 20;
int &r = i; //r 是变量i的引用
int &s; //错误,声明引用时必须初始化
i = 15; //i 和 r 都等于15
i++; //i 和 r都等于16
r = 18; //i 和r 都等于18
printf("Address of i=%u, Address of r=%u",&i,&r); //内存地址相同
r = j; //i 和 r都等于20,但r不是j的引用
r++; //i 和 r 都等于21, j 仍等于20
}
用const修饰引用,使应用不可修改,但这并不耽误引用反映任何对变量的修改。Const加在数据类型前后均可。
例如:
void main(void)
{
int i = 10;
int j = 100;
const int &r = i;
int const &s = j;
r = 20; //错,不能改变内容
s = 50; //错,不能改变内容
i = 15; // i和r 都等于15
j = 25; // j和s 都等于25
}
第四:Const和成员函数
声明成员函数时,末尾加const修饰,表示在成员函数内不得改变该对象的任何数据。这种模式常被用来表示对象数据只读的访问模式。例如:
class MyClass
{
char *str ="Hello, World";
MyClass()
{
//void constructor
}
~MyClass()
{
//destructor
}
char ValueAt(int pos) const //const method is an accessor method
{
if(pos >= 12)
return 0;
*str = 'M'; //错误,不得修改该对象
return str[pos]; //return the value at position pos
}
}
第五:Const和重载
重载函数的时候也可以使用const,考虑下面的代码:
class MyClass
{
char *str ="Hello, World";
MyClass()
{
//void constructor
}
~MyClass()
{
//destructor
}
char ValueAt(int pos) const //const method is an accessor method
{
if(pos >= 12)
return 0;
return str[pos]; //return the value at position pos
}
char& ValueAt(int pos) //通过返回引用设置内存内容
{
if(pos >= 12)
return NULL;
return str[pos];
}
}
在上面的例子中,ValueAt是被重载的。Const实际上是函数参数的一部分,在第一个成员函数中它限制这个函数不能改变对象的数据,而第二个则没有。这个例子只是用来说明const可以用来重载函数,没有什么实用意义。
class MyClass
{
char *str ="Hello, World";
MyClass()
{
//void constructor
}
~MyClass()
{
//destructor
}
char& operator[](int pos) //通过返回引用可用来更改内存内容
{
if(pos >= 12)
return NULL;
return str[pos];
}
}
void main(void)
{
MyClass m;
char ch = m[0]; //ch 等于 'H'
m[0] = 'M'; //m的成员str变成:Mello, World
}