在初步学习C++语法的过程中,有特别明显的感受:const是一个十分重要的C++特性,彻底掌握它很有必要。
顶层const与底层const
想要很好地掌握const的概念,必须要能够正确的理解“变量的声明格式”,基本要求是必须要念对。
const int *ptr //ptr是一个指向const int类型的指针(ptr是一个指向整数常量的指针)
int *const ptr //ptr是一个指向int类型变量的常指针
以上这两种定义方法是很好念的,下面这个需要额外注意:
int const *ptr //ptr是一个指向const int类型的指针
我们应该记住这一种定义,
const修饰变量,以下两种定义形式在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的。
TYPE const ValueName = value;
const TYPE ValueName = value;
(引用自YoungWang的博客)
因此,我们对于指针和变量都是const的变量也能有两种方式定义,
const type const *p
const type *const p;
我们可以看一下编译结果是否一样。(到时候补充)
补充内容,汇编出来确实是一样的
同理,引用也是按照上述规则推导的。
一般的,顶层const是指不可被修改的常量对象。顶层const要考虑到指针和引用的性质。指针既可以是顶层const也可以是底层const,引用一定是底层const。
下面要强调的是顶层const和底层const在复制方面的区别,其实只要记住一个原则:常量不能够转换成非常量即可。
C++中各指令与const有关的规定
顶层const和引用const保留,忽略底层const。
类型转换——特别是const的类型转换
static_cast <type> exp //对于任何能够隐式转换的变量都可以转换
const_cast //可以用于在运算时临时删去引用的const的限制
const与函数的参数传递
当为函数传递形参时,等于在函数中新定义了一个变量(可以用函数栈来理解),因此,这个过程是值传递,不论形参类型是const与否,实参都可以是任意类型。
然而,在传递指针和引用的时候情况有所不同。这时候的参数传递可以看成是一种二重指针或者引用——指针的形式。在这种情况下,必须要求底层的const类型相同,法则也是:非常量可以转为常量,常量则不能转为非常量。
const与函数重载
由于上一个栏目的规则,可以通过设计底层const来区分重载参数,前提是他们必须要拥有底层的指针或者引用。
考虑以下的代码:
void f(int &x);
void f(const int &x);
void g(int *x);
void g(const int *x);
int main()
{
int a;
const int b;
f(a);
f(b);
g(a);
g(b);
}
由于底层const可以重载,这样的调用是成立的。