const 作⽤
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
一、 修饰变量,说明该变量不可以被改变
声明的时候必须初始化
,一旦声明,这个值将不能被改变
int val = 100;
const char a;//错误,未初始化
const int b = val;//正确,此时a为一个常量,不能被改变
b = 28;//错误,a为常量,不能当作左值
二、 修饰指针,分为常量指针和指针常量
常量在后,指针的指向不可以修改
常量在前,指针的指向可以修改
主要看const修饰哪里
const int *p=&a;//const修饰*p(指针指向的值不可以修改)常量指针
int *const p=&a;//const修饰p(指针的指向不可以修改)指针常量
const int *const p=&a;//都修饰(都不能修改)
三、 常量引⽤,经常⽤于形参类型,即避免了拷⻉,⼜避免了函数对值的修改
- 对于
值传递
的参数来说,没必要加const修饰,因为函数将会自动产生临时变量用于复制该参数。 - 对于
引用传递
和指针传递
的参数,如果不想原来参数被改变的话,可以加const修饰,防止意外的改动。 - 引用传递的好处:仅借用参数的别名而已,不需要产生临时变量。
void test1(int a, char *b, float &c);//普通入参
void test2(const int a, const char *b, const float &c);//const修饰的入参
四、修饰函数返回值
- 如果函数的返回值是一个
值
,则加const无意义。 - 如果函数的返回值是一个
地址
(比如指针函数),加const修饰 则返回值的内容不能被修改,必须赋给同类型的指针变量来接收
const int fun1(int a);
const char *fun2(char b);
const Person &fun3(Person p);//Person是自定义的类。返回值采用引用 不常用
//主调函数
int main()
{
char ch='a';
const char *p=fun2(ch);//正确
char *p=fun2(ch);//错误
}
五、 const修饰成员函数,说明该成员函数内不能修改成员变量,也不能调用非const成员函数
class Person
{
public:
int fun1(char a);
double fun2(float b);
char fun3(int c) const;
int value;
};
int Person::fun3(int c) const
{
char ch='o';
value++;//错误,不能修改成员变量
fun1(ch);//错误,不能调用非const成员函数
}
const本质
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。可以修改复合数据类型的的属性。
class Person
{
public:
void fun(int a);
void fun1(int a) const;
}
fun函数其实有两个参数:
void fun(Person *this, int a);
第一个参数是Person *const this(this 就代表指向该函数所作用的对象的指针)
在fun1函数后面加const相当于:
void fun(Person *const this, int a);
此时指针的指向不能改变