指向const对象的指针
如果指针指向const对象,C++语言强制要求指向const对象的指针也必须具有const特性。
const int a = 10;
const int *pa = &a;
const限定了pa指针所指向的对象本身,而并非pa本身,即允许给pa重新赋值,但不允许通过pa改变a的值。即:
const int a = 10;
const int b = 20;
const int *pa = &a;
*pa = 20; //错误,不允许通过pa改变a的值
pa = &b; //正确,允许给pa重新赋值
注意:
- 不能把一个 const 对象的地址赋给一个非 const 对象的指针
- 不能使用 void* 保存 const对象 的地址,得使用 const void*
- 允许把 非const对象 的地址赋给 const修饰的指针,但是一旦把 非const对象 的地址赋值给 const修饰的指针,就不能通过 const指针 修改所指向的变量,但变量本身是可以修改的。即:
int a = 10;
const int *pa = &a;
*pa = 20; //错误,不能通过 const指针 修改所指向的变量
a = 20; //正确,变量本身可以修改
cout << *pa << endl; //最后输出结果为20
const指针
上面我们说过,对于指向const对象的指针,虽然不能通过指针修改指向的变量,但是指针本身是可以再赋值的。
除了上面的指针外,C++还提供了一种const指针 – 指针本身的值不能改变。
int a = 10;
int *const pa = &a;
对于这种形式的指针,指针pa值便不可修改,但是pa指向的值可以修改,即:
int a = 10;
int b = 30;
int *const pa = &a;
*pa = 20; //这样是正确的,pa指向的值可以修改
pa = &b; //这样写是错误的,指针pa值不可修改
注意:
- 对于第一种指向const对象的指针,因为指针本身并不是const,所以在定义时不需要初始化。
- 对于第二种const指针,因为指针本身是const修饰的,与任何const变量一样,const指针也必须在定义的时候初始化。
指针和typedef
在typedef中使用指针往往会带来意外的结果,看下面的例题:
typedef string *pstr;
const pstr cstr;
请问cstr是什么类型?
可能乍一看,const pstr cstr <=>
const string *cstr,但这是错误的。因为我们都知道如果指针本身并不是const,只是指向const对象,那么在定义时不需要初始化;如果指针本身const 指针,那么必须在定义的时候初始化,就如同下面一样:
const int *pint; //可以不用初始化
int *const ppint; //不可以不初始化,这样写是错误的
我们把
typedef string *pstr;
const pstr cstr;
写到编译器里,编译器会提示错误,说明 const pstr cstr 不初始化是错误的,所以 const pstr cstr!=
const string *cstr
错误的原因在于将 typedef 当做文本扩展了。声明 const pstr 时,const修饰的是pstr,pstr是一个指针。因此,该声明语句应该是把cstr定义为指向string类型的const指针,所以:
const pstr cstr <=>
string *const cstr