const限定符是常用且容易混淆的概念,很多书中讲解不清晰,甚至《C++ primer》中都有一些错误的论断或者不明确的区分,本文对const限定符做归纳总结。
一、在类型中
顶层const和底层const是一个非常容易让人遗忘和混淆的概念,这里包括常量词性(即使名词常量,也是形容词常量的)和C++类型定义从右向左的释义顺序与日常语言从左向右理解的顺序差异造成的混淆。
首先将常量指针和指向常量的指针加以区分:
1.1 const pointer V.S. pointer to const
a) const pointer 常量指针 (其实英文语义很明显,没有歧义,中文隐藏了“的”,即常量的指针)
这里的const和常量是形容词,其实表示的是常量的指针。指的是指针本身是常量。但C++语法的释义并非是正常的从左向右读,而是从右向左解释,例如:
int errNumb=0;
int *const ptr=& errNumb; //从右向左释义:ptr是常量的*(指针),指针指向int类型的对象,即常量指针指向int类型的对象
即我们说的常量指针const pointer在C++语法中实际是写成* const
禁止修改常量指针的值。
b) pointer to const指向常量的指针
这里的const是名词。
const double pi=3.14;
const double *cptr=& pi; //从右向左释义:cptr是*(指针),指针指向double类型的对象,double类型的对象是const的,即指针指向double类型的常量
对于指向常量的指针,禁止通过指针修改指向的变量的值。
c) const pointer & pointer to const
const double pi=3.14;
const double *const cptr=& pi; //从右向左释义:cptr const的*(指针),指针指向double类型的对象,double类型的对象是const的,即常量指针指向double类型的常量。其中第一个const是pointer to const(即底层const),第二个const是const pointer(即顶层const)
1.2 顶层const与底层const
- 顶层const可以表示任何数据类型是(自身)常量,例如:int , double, *, class等;
- 底层const表示指针和引用的复合类型的基本类型部分是常量。
指针是对象,因此既有顶层const(指针本身),也有底层const(指针所指的对象)。
引用不是对象,因此只存在reference to const / 对常量的引用,即底层const, 不存在顶层const/常量引用。(注意:《C++ primer》中文版中2.4.1的标题写的是const的引用,显然是错误的,引文版中的题目是references to const,大家不要被常量引用的说法误导,并没有常量引用,只有对常量的引用)
总结:reference