【c++11】const与constexpr

const大家都知道,当我们希望定义一种变量,它的值不能被改变时使用。

一 初始化时注意几点

1.定义时必须初始化

const int i = 42;//correct
const int k;//wrong,const should be initialized

2.可以用非常量初始化

int i = 42;
const int j = i;//正确,拷贝完成后j的值与i没什么关系了

3.默认情况下仅在文件内有效

如果多个文件声明了同名const变量,编译器认为是不同的变量。若要在多个文件中使用同一个const,需要在声明和定义时,均添加extern关键字,这样只需要定义一次就可以了。

二 const的引用

对const的引用虽然简称为“常量引用”,引用对象是常量还是非常量只是可以决定其所能参与的操作,却不会影响到绑定关系本身。事实上,c++语言不允许随意改变引用绑定的变量,所以又可以理解为所有引用都是常量引用(引用关系为常)。

引用对象可以是个非常量,常量引用仅仅对引用可参与的操作做出限定,例如:

int i = 42;
const int &r2 = i;
r2 = 0;//错误,不能通过r2改变i

所谓常量的指针或引用,不过是指针或引用自身认为指向了常量,因此”自觉地”不去改变所指对象的值。

三 const指针

常量指针必须初始化,且初始化后,值不能再改变了。

int errNumb=0;
int *const curErr=&errNumb;

四 顶层与底层

顶层const:指针本身为常量 (不能改变值)

底层const:指针所指对象为常量 (可以改变值)

int i = 0;
int *const p1 = &i;//不能改变p1的值,是顶层const
const int ci =42;//不能改变ci的值,这也是个顶层const
const int *p2 =&ci;//可以改变p2的值,这是个底层const

非常量可以转为为常量,反之不行。

五 constexpr和常量表达式

c++11规定:允许将变量声明为constexpr类型以便编译期验证变量的值是否是一个常量表达式

constexpr int sz=size();

在上述例子中,只有当size()是一个constexpr函数时,这条声音语句才正确。

常量表达式:值不会变,且在编译过程中就能得到计算结果的表达式。

const int sz = function();//sz不是常量表达式,尽管sz本身为一个常量,但fucntion()值无法在编译阶段获取

const与constexpr区别在于:

1.const未区分编译期常量和运行期常量,constexpr限定编译期常量。

2.constexpr声明中如果定义了指针,constexpr也只对指针有效,对所指对象无效。即constexpr只能顶层。

const int *p=0;//p是指向常量的指针
constexpr int *p1 =0;//p1是指向整数的常量指针

六 auto与const

auto会忽略顶层const,保留底层const。

const int ci=i;
auto b = ci;//b是一个整数,ci的顶层const属性被忽略
auto e= &ci;//e是一个指向整数常量的指针,因为对常量取地址是一种底层const


你可能感兴趣的:(c++)