1.const用于指针
第一种形式:如type *const 指针变量;
int *const p; //指向整形的常量指针 ,它不能再指向别的变量(p的值不能改变),但指向(的变量)的值可以修改。
第二种形式:如const type * 指针变量; vs type const * 指针常量
const int * p; //指向整形常量的指针,它所指向(的变量)的值不可以更改
int const * p;
第三种形式:如 const int * const p;
指向整形常量的常量指针,它既不能再指向别的常量,指向的值也不能进行修改。
申明的技巧:
关键字const右边来确定什么被声明为常量 ,如果该关键字的右边是类型,则值是常量;如果关键字的右边是指针变量,则指针本身是常量 。
2.const用于函数的地址传递参数,修饰函数的参数
void foo(const int *p);
这种形式通常用于在数组形式的参数中模拟传值调用。
也就是相当于函数调用者声称:“我给你一个指向它的指针,但你不能去修改它。”
如果函数编写者遵循了这个约定,那么就相当于模拟了值传递。
这也是const最有用之处了:用来限定函数的形参,这样该函数将不会修改实参指针所指的数据。
这里注意了,是函数不应该去修改而不是不能修改,也就是说const不能阻止参数的修改。
3.const修饰函数的返回值
const int foo();
上述写法限定函数的返回值不可被更新,当函数返回内部的类型时,已经是一个数值,当然不可被赋值更新。
所以,此时const无意义,最好去掉,以免困惑。
如果给以“指针传递”方式的函数返回值加上const修饰,那么函数返回值(即指针指向)的内容不能被修改。
该返回值只能被赋给加const修饰的同类型指针。例如:
const char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();
正确的用法是
const char *str = GetString();
const struct mytype foo();
当函数返回自定义的类型时,这个类型仍然包含可以被赋值的变量成员,所以,此时有意义。
4.const修饰成员函数
关于const函数的几点规则:
a. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数。
b. const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的。
c. const成员函数不可以修改对象的数据,不管对象是否具有const性质。它在编译时,以是否修改成员数据为依据,进行检查。
d. 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的。
5.const用法实例
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
int a=3;
int b;
//定义指向整形const(常量)的指针,即指针指向的内容不可修改
const int * p1;
int const * p2;
//定义const(常量)指针,由于该类指针本身的值不能改变所以必须得初始化
int *const p3 = &a;
//常量指针及它所指向的整形常量都是不能改变的,所以也要初始化。
const int * const p4 = &a;
int const * const p5 = &b;
p1=p2=&a; //正确
//试图改变指针指向的整形常量?
// *p1=*p2=8; // 错误(指针指向的内容不能被修改)
cout<<*p1<<endl;
*p3=5; //正确
// p3 = p1; 非法操作
// p4 = p4; 非法操作
// *p4 = *p5 =9; 非法操作
cout<<*p1<<endl;
cout<<*p4<<endl;
cout<<*p5<<endl;
return 0;
}