> 文章列表 > C/C++程序设计——const关键字

C/C++程序设计——const关键字

C/C++程序设计——const关键字

1.修饰变量

1.1 作用

功能:不能直接被修改

        const修饰变量,就相当于是定义了一个常量。该变量不能直接被修改,但是可以通过指针修改。

作用:便于维护、提前发现可能错误的修改

        比如程序中大量使用了一个数字10,且不会对其修改,就可以将其定义为const常量,这样若其他地方对其进行了直接修改,编译阶段就会报错;且以后如果要改变这个数字,那么只需要改变定义时这一个地方就可。

1.2 修饰局部变量

(1)C环境下

(2)C++环境下(常量折叠)

在C++环境下,我们运行同上代码:

        我们发现通过指针修改后, val还是输出的10,*p输出的是20,两个的地址也是一样的,但输出值不同,这是什么原因?

常量折叠:

        这就是C++中的常量折叠:const变量(即常量)值,会被存放到编译器的符号表中,参与计算时直接从符号表中取出数据,省去了内存访问的操作,这就是编译器进行的一种优化。编译器在预处理的时候,就对const变量val进行了替换(只读取了这一次),所以输出的是原先的10,而*p指向的是val的存储空间,也实际改变了val存储的数据,所以输出的是20。

const修饰的局部变量:是存储在栈区中。

解决方法:

        使用volatile关键字修饰该变量,保持变量的内存可见性,这样每次访问该变量内容时,都会通过内存去获取。

 

1.3 const修饰全局变量(C/C++)

        上述内容是在局部const变量条件下,若const修饰的是全局变量,再通过指针去修改,则会引发异常,写入访问权限冲突,也就是不可写。

原因:const修饰的全局变量存储在内存的全局区中,其只有可读属性,无法修改。

2.修饰指针

2.1 指针常量

指针常量:const修饰指针变量名

        表示指针的指向不能被修改,但是指向的内容可以被修改。

2.2 常量指针

常量指针:const修饰*

        表示指针指向的内容不能被修改,但是指针的指向可以修改。

注意:

        当然也可以利用两个const分别修饰*和指针变量名,表示该指针的指向和指向的内容都不能被修改。

 

3.修饰数组

        表明数组中的每个元素都是const属性,其特性同上。

4.修饰函数形参

(1)void func(const int val);

        形参不能被修改。

(2)void func(const int* val);

        指针形参指向的内容不能被修改,因为实参和形参指向的是同一个地址,所以可以防止函数内部通过形参进行修改其指向内容,起到保护实参指向内容的作用。

(3)void func(int* const val);

        指针形参的指向不能被修改。

(4)void func(const int& val);(C++)

        引用实体无法被修改,保护实体。注意:const放到&符号后不起作用。

注意:const实参不能传递给非const形参;非const实参可以传递给const形参。

5.修饰函数返回值

5.1 修饰普通类型返回值

        没有意义,因为返回的本身就是一个临时变量,具有常量性。

5.2 修饰指针类型返回值

(1)const修饰*

        不能将权限放大,所以不能赋值给非const属性变量。

(2)const修饰指针变量名(在*后面)

        此时可以将其赋值给非const变量,因为此时指针指向的内容可以被修改,将其赋值给非const变量后,也可以对其指向的内容进行修改,并没有放大对指向内容的访问权限。

5.3 修饰引用类型返回值(C++)

        同样只能赋值给const类型引用,表示不能对引用实体进行修改。

6.修饰类的成员变量(C++)

        const修饰类的成员变量,表示其为成员常量,不能被修改,且只能在初始化列表进行初始化。(注:C++98和11中,也支持了声明时初始化,但还是推荐使用初始化列表进行初始化)

7.修饰类的成员函数(C++)

        const修饰的类成员函数称为const成员函数,本质上const修饰的是该成员函数隐藏的this指针,表示在该函数内,不能对类的任何成员进行修改

this本身的类型:Time* const this

const修饰后:const Time* const this

        相当于this本身的指向就是不能被修改的,通过const成员函数的const修饰后,其指向的内容也不能被修改。

相关问题:

(1)const对象能否调用非const成员函数?

        不能,const类型对象只能调用const成员函数,不能调用普通成员函数。因为普通成员函数可能会对对象中的成员进行修改。

(2)非const对象能否调用const成员函数?

        可以,普通对象对于普通成员函数和const成员函数都可以调用。

(3)const成员函数内,能否调用其他的非const成员函数?

        不能,同理非const成员函数可能会对对象的成员进行修改,而const成员函数内不能对对象的任何成员进行修改。

(4)非const成员函数内,能否调用其他的const成员函数?

        可以。

注意:

        构造函数,拷贝构造函数,析构函数,赋值运算符重载,不可以使用const修饰。因为以上四个函数目的就是对成员进行修改。

mutable关键字:
        mutable关键字修饰成员变量,表示该成员变量可以在const修饰中被修改。