在C++中const 是一个很重要的标识符,其定义是值被初始化以后不能被改变的变量,但是其用法却千变万化,现总结如下:
const和基本类型
从const的定义中可以看出,const是定义以后不能被改变的量,所以const 对象必须被初始化,且初始值可以是任意复杂的表达式,例如对于如下代码段,这两种声明初始化方式都是合法的。
const int i=42;
const int j=get_size();
如果我们试图堆已经初始化过的const 变量重新赋值将会报错,例如,堆上面已经定义过的变量i,如果我们用另外一个整型变量去给他赋值将会报错:
```cpp
int k=0;
i=k
;
编译器将会显示错误:不能给常量赋值,即使k也是42也不行。但是反过来,我们可以用const给普通变量赋值,例如:
```cpp
const int buffSize=512;
int a=buffSize;
这样的语句是合法的。
同时,const对象的自增和自减运算符也是非法的,例如:
const int buffSize=512;
buffSize++;
编译器会报错:表达式必须是可以修改的左值。
2.const和引用
在C++中引用是变量的别名,引用和指针类似但是又不一样,指针是一种数据类型,只是其指向的地址为当前变量,引用则只是对象的另外一个名字。和const一样,引用也必须被初始化,和赋值操作不一样,赋值操作相当于是把一个变量的值拷贝出来给另外一个变量,这两个变量存储的地址是不一样的,引用的话,两个变量的地址实质上是一的;例如对于如下代码段(此时&是取地址运算符):
int a=1;
int b=a;
cout<<&a<<endl;
cout<<&b<<endl;
这样是将变量a拷贝给变量b,他们两者的地址是不一样的:
0073FBA0
0073FB94
对于引用,例如如下代码:
int a=1;
int &b=a;
cout<<&a<<endl;
cout<<&b<<endl;
他们的输出为:
004FFC30
004FFC30
两者的地址是一样的,值得一提的是&运算符在不同的情况下含义是不一样的,有时候是取地址运算符,有时候是引用符号,注意区分使用场景。
在const中,可以把引用绑定到一个常量对象上,称为对常量的引用,对常量的引用不能被用作修改他所绑定的对象,什么意思呢,因为引用的本质是对象的别名,因此对引用的改变实际上也改变了引用所绑定的对象,例如:
const int a=1;
const int &b=a;
b=43;
这样将会报错,同时,如果用非常量引用去绑定常量对象也会报错,例如:
const int a=1;
int &b=a;
这样是非法的,编译器会报错:无法从“const int”转换为“int &” 。
如果反过来则是合法的,例如:
int a =1;
const int &b=a;
实际上,编译器在执行上述代码时候,会将a 转换为一个临时常量再用b绑定该临时常量,这样下来,a 是可修改的,b是不可修改的。
3.const 和指针
指针和引用不一样,指针本身也是一个独立的变量,我们知道指针的类型是由指针前面的修饰符所决定的,例如,int*p,则p是一个指向整型的指针,同样的,在const 中有指向常量的指针,指向常量的指针不能用于改变其所指向的常量对象,例如:
const int a=1;
const int *p=&a;
上述语句是合法的,因为p是一个指向常量的指针,他指向的也是常量对象。但是如果试图给p赋值将会出现错误,例如:
const int a=1;
const int *p=&a;
*p=2;
这样的语句是非法的,编译器会报错。
但是,指向常量的指针也可以指向非常量的对象,例如:
int a=1;
const int *p=&a;
cout<<*p<<endl;
这样的输出值将是1,注意一点,指向非常量的指针不饿能用于修改其指向的对象的值,例如:
int a=1;
const int *p=&a;
*p=2;
这样编译器也会报错。
除了指向常量的指针意外,还有常量指针这一概念,常量指针意味着指针本身不能改变,但是并不意味着指针指向的值不能改变,例如:
int a=1;
int *const p=&a;
a++;
cout<<*p<<endl;
p是一个常量指针,p的值本身不能被改变,但是p所指向的值可以改变,例如,上述输出就是2。但是如果试图改变p本身,编译器会报错:
int a=1;
int *const p=&a;
int *q;
p=q;
这样的语句是非法的,相比于指向常量的指针,指针本身可以变化,但是其所指向的值不能通过指针来改变(但是可以自己改变)
int a=1;
const int *p=&a;
int b=2;
const int *q=&b;
p=q;
cout<<*p<<endl;
这样的语句是合法的,其输出值是2.
4.函数和const
C++允许哈数传入const形参,但是不允许改变该参数的值,例如:
void fun(const int i)
{
cout<<i<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
fun(1);
}
这样的调用是合法的,但是如果试图修改形参的值,例如:
void fun(const int i)
{
cout<<i++<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
fun(1);
}
样的调用是非法的。
除此之外,还能定义const成员函数,如果在一个类中定义了const成员函数,那么该函数不能改变类的成员变量,例如:
class constTest
{
public:
constTest(void);
~constTest(void);
void fun() const;
private:
int i;
};
constTest::constTest(void)
{
i=1;
}
constTest::~constTest(void)
{
}
void constTest::fun()
{
i++;
}
我们定义一个constTest类,该类中在构造函数中初始化i=1,但是如果通过const 成员函数去改变变量的值将会报错。