在C++里面,const关键字的用处很多,使用好const关键字对程序的健壮性大有好处。
首先来看看const一般都用在什么地方。
1.用于定义常量。
const用的最多的就是用来定义常量了。
const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误。
一个最简单的例子:
#include <iostream> using namespace std; int main() { const int i=5; cout<<"i="<<i<<endl; //i=10; //cout<<"i="<<i<<endl; };
这样运行时毫无问题的,但是如果你想给i重新赋值i=10的时候就会报错!
2.让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值。
例如:
#include <iostream> #include <string> using namespace std; int main() { int i=20; const int* p=&i;//令p指向i,并且不能通过p修改i cout<<*p<<" address:"<<p<<endl; //*p=21; i=15; cout<<*p<<" address:"<<p<<endl; };
const int* p=&i;该声明指出了p是一个指向const int的指针,因此不能使用p来修改这个值。
换句话说,*p的值为const,是不能修改的。注意:这样就可以禁止通过p来修改i的值,例如*p=21这样的操作时不允许的。p的声明并不意味着它所指向的值就是一个const常量,而只是意味着对于p而言,这个值是const,但是这并不能说明i是一个不能修改的值,例如i=15,这样的操作时允许的。
并且,p指向的位置是可以改变的,例如:
#include <iostream> #include <string> using namespace std; int main() { int i=20; const int* p=&i; cout<<*p<<" address:"<<p<<endl; //*p=21; int k=15; p=&k; cout<<*p<<" address:"<<p<<endl; };运行结果:
可以看出,p所指向的地址已经改变了!
3.将指针本身声明为常量,这样可以防止修改指针指向的位置。
例子:
<pre name="code" class="cpp">#include <iostream> #include <string> using namespace std; int main() { int i=20; int* const p=&i;//注意const的位置 cout<<*p<<" address:"<<p<<endl; *p=21; int k=15; p=&k;//invalid cout<<*p<<" address:"<<p<<endl; };
编译的时候会报错。
p=&k,操作不允许,说明了p所指向的位置是const,不可修改的。
但是可以通过*p来修改其所指向位置的值。
还有一点就是:
以前我们将常规变量的指针赋给常规指针,而这里将常规变量的地址赋给指向const的指针。因此有两种可能。
一种是:将const变量的地址赋给指向const的指针,第二种是将const的地址赋给常规指针。这两种操作都可行吗?
显然第一种可以,而第二种是不可以的。
例如:const int i=10;
int *p=&i;//invalid
如果这是可行的,那么就能通过p修改i的值,那么const int i这一句声明里面的const状态就相当于无效了。
当然,如果一定要转换,通过const_cast还是可以突破这种限制的。但是也是有限制的。
例如:
#include <iostream> #include <string> using namespace std; int main() { const int pos1=20; int pos2=20; //pp1,pp2均是const int*,但只有pos1是const const int* pp1=&pos1; const int* pp2=&pos2; int *p1=const_cast<int *>(pp1); int *p2=const_cast<int *>(pp2); *p1=15; *p2=15; cout<<"pos1="<<pos1<<endl; cout<<"pos2="<<pos2<<endl; //p2改变了pos2的值,但p1不能改变pos1的值,因此,仅当const指针(pp2)指向的值(pos2)不是const类型的,才能通过该const指针(pp2) //突破修改该值(pos2)。 };
感觉文章有点长了,关于const在方法以及参数引用的请看下一篇博文。