C++中const的各种用法的详解
const名叫常量限定符,用来限定特定变量,以通知编译器该变量是不可修改的。习惯性的使用const,可以避免在函数中对某些不应修改的变量造成可能的改动。
1. const修饰基本数据类型
1.1 const修饰一般常量及数组
|
|
对于类似这些基本数据类型,修饰符const可以用在类型说明符前,也可以用在类型说明符后,其结果是一样的。在使用这些常量的时候,只要不改变这些常量的值便好。
1.2 const修饰指针变量*及引用变量&
1.2.1 指针*和引用&的一些基本知识
介绍本部分内容之前,先说说指针和引用的一些基本知识。
指针(pointer)是用来指向实际内存地址的变量,一般来说,指针是整型,而且一般的大家会接受十六进制的输出格式。 引用(reference)是其相应变量的别名,用于向函数提供直接访问参数(而不是参数的副本)的途径,与指针相比,引用是一种受限制的指针类型,或者说是指针的一个子集,而从其功能上来看,似乎可以说引用是指针功能的一种高层实现。
关于运算符&和*: 在C++里,沿袭C中的语法,有两个一元运算符用于指针操作:&和*。&是取址符,*是指针符,也就是说,&用于返回变量的实际地址,*用于返回地址所指向的变量,他们应当互为逆运算
在定义变量的引用的时候,&只是个定义引用的标志,不代表取地址。
|
|
运行结果:
|
|
1.2.2 const修饰指针(*)
|
|
|
|
|
|
|
|
可以参考《Effective c++》Item21上的做法,
如果const位于星号*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于星*号的右侧,const就是修饰指针本身,即指针本身是常量。
因此,[1]和[2]的情况相同,都是指针所指向的内容为常量,这种情况下不允许对内容进行更改操作,如不能*a = 3 ;
[3]为指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如a++是错误的;
[4]为指针本身和指向的内容均为常量。
1.2.3 const修饰引用(&)
|
|
2. const应用到函数中
2.1 const 修饰函数参数
如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。
const 只能修饰输入参数,可以分为三种情况:
- 值传递的不用 const 修饰
值传递参数一般不需要 const 修饰,因为函数会自动产生临时变量复制实参值。
并且对于一般的 int、double 等内置类型,一般采用值传递方式。
不要将函数 void Func1(int x)
写成 void Func1(const int x)
。同理不要将函数 void Func2(A a)
写成 void Func2(const A a)
。其中A 为用户自定义的数据类型。
- const 修饰指针时,可以防止指针被意外篡改。
|
|
- const 修饰自定义类型的参数
定义类型的参数如采用值传递,临时对象将会复制参数,需要用构造函数,比较浪费时间,一般采用 const 外加引用传递的方法。
|
|
2.2 const 修饰函数返回值
- const 修饰“值传递”方式的的函数返回值,由于函数会把返回值复制到外部临时的存储单元中,加 const 修饰没有任何价值,修饰与不修饰返回值作用一样。
不要把函数 int GetInt(void)
写成 const int GetInt(void)
。
- const 修饰以“指针传递”方式的函数返回值,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
|
|
- const 修饰“引用传递”作为返回值,此时返回的值不能作为左值使用,既不能被赋值,也不能被修改。
|
|
这个时候为了避免成员函数被修改就需要加上const关键字,这个时候如果试图改变返回值是不允许的。
需要指出的是,如果函数的返回类型是内置类型,比如 int char 等,修改返回值本身就是不合法的!所以 const 返回值是处理返回类型为用户定义类型的情况。
2.3 const 修饰在函数名后面
在函数名后面表示是 C++ 常成员函数,该函数不能修改对象内的任何成员,只能发生读操作,不能发生写操作。
const 修饰成员函数, 根本上是修饰了 this 指针。
注意:const 关键字不能与 static 关键字同时使用,因为 static 关键字修饰静态成员函数,静态成员函数不含有 this 指针,即不能实例化,const 成员函数必须具体到某一实例。
|
|
- const 对象只能访问 const 成员函数,而非 const 对象可以访问任意的成员函数,包括 const 成员函数.
- const 对象的成员是不可修改的,然而 const 对象通过指针维护的对象却是可以修改的.
- const 成员函数不可以修改对象的数据,不管对象是否具有 const 性质.它在编译时,以是否修改成员数据为依据,进行检查.
- 然而加上 mutable 修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的 const 成员函数是可以修改它的