【c++11】const与constexpr

本文详细解析了C++中const的用法,包括变量声明、引用、指针等多个方面,并对比了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++ 中 `const` `constexpr` 的区别使用场景 #### 定义基本概念 `const` `constexpr` 都用于表示不可变的数据,但在语义用途上有显著差异。`const` 主要用来表达“只读”的含义,而 `constexpr` 则更进一步,强调数据可以在编译期计算并确定其值[^1]。 #### 编译期运行期的支持 - **`const`**: 表示变量在初始化之后不能再被修改。它的值可能是在运行时才确定的,因此不一定能在编译期求值。 - **`constexpr`**: 不仅具备 `const` 的不可修改特性,还能确保该值在编译期就被计算出来。这意味着它适用于需要静态常量的场合,比如数组大小或模板参数等[^3]。 #### 类型支持 - **`const`**: 可以应用于任何类型的对象,无论是基础类型还是复杂类的对象。 - **`constexpr`**: 对于函数返回值或者变量初始值有严格的要求——它们必须能够通过简单的表达式来计算得出,并且这些操作数也应该是字面量(literals),或者是其他已经声明为 `constexpr` 的实体[^4]。 #### 使用建议 为了更好地利用这两种关键字的不同特点,在实际编码实践中可以遵循如下原则: - 当只需要表明某个东西不应该改变的时候(即使这个不变性只是逻辑上的),应该优先考虑使用 `const` 关键字; - 如果希望某项数值不仅保持恒定而且能够在编译期间得到解析,则应当选用 `constexpr`[^1]。 以下是两个简单例子展示如何正确运用这两个关键词: ```cpp // Example of using 'const' const int max_size = 10; // Runtime constant, cannot be used as non-type template parameter. // Example of using 'constexpr' constexpr double pi = 3.14159265358979323846; // Compile-time constant. ``` #### 总结 虽然两者都能创建不可更改的变量,但因各自特性的不同决定了各自的适用范围。对于那些仅仅需要保护免受意外改动影响的情况来说,采用 `const` 就足够了;而对于那些确实有必要提前知道确切数值的情形下,则更适合应用 `constexpr`[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值