news 2026/5/12 19:47:04

跟我学C++中级篇——对类const关键字的分析说明

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
跟我学C++中级篇——对类const关键字的分析说明

一、说明

前面多篇文章分析了常量的各种用法以及在新标准中的各种扩展。到目前为止,可以发现有几个长得差不多的关键字:从早期的const到C++11中的constexpr直到C++20中的consteval和constinit。这些长得类似的const有什么区别和联系呢?下面就对它们的具体应用进行分析和说明。

二、对比和分析

针对上面的这些长得差不多关键字,主要有以下的不同:

  1. const
    它是在C++中传统,const主要用来控制运行时对变量和表达式的只读性的控制。目的在于保护相关数据的安全性并进行接口的约束。其约束的变量可以根据时机在编译期或运行期进行求值
  2. constexpr
    C++11中引入的constexpr,用于在编译期的计算,也就是编译期求值,同时对变量和表达式的只读性控制。可以将运行期的计算转到编译期的计算和常量表达式的处理,当然,也支持运行期的处理
  3. consteval
    作为C++20引入的constexpr,主要用于立即函数处理,即它只能修饰函数,它修饰的函数及相关调用及相关求值都强制要求必须在编译期完成
  4. constinit
    constinit也是C++20引入的,它只能用于对静态或线程局部变量进行“常量初始化”(constant initialization)即编译期完成初始化。否则,会报编译错误。需要注意的是,它只能是初始化,完成后,这个变量是可以再次修改的即这个变量不是常量。

三、应用场景和限制分析

在了解上它们四个关键字的情况后,就可以根据其特点来确定其应用场景:

  1. 编译期计算
    需要在编译期计算的场景下,可以使用constexpr和consteval,这样,就可以把运行时的开销转移到编译期。另外在模板和元编程中这两个关键字也是经常使用的
  2. 接口约束和数据只读
    在与旧代码兼容以及需要接口的常量化控制,并且只是需要对数据常量化的处理时,可以考虑使用const。当然,很多情况下也可以使用constexpr
  3. 强制常量初始化
    在前面也提到过,在C++库中的全局(静态)变量调用时可能会产生初始化顺序的问题,从而产生意想不到的问题。而如果使用constinit则可以避免相关变量动态初始化,从而保证变量的依赖安全性。此外在全局配置处理、跨编译单元的变量以及线程局部存储等场景下都可以应用

虽然constinit无法限制变量的常量性,但它却也不允许联合使用const和constexpr来限制变量的常量性(只读性)。而const和constexpr则可以联合使用,不过是一种冗余的应用,没有什么实际意义。

四、例程

下面看一下具体的例程的对比:

//下面代码来自 cppreference//constexprconstexprintf();constexpr bool b1=noexcept(f());// false, undefined constexpr functionconstexprintf(){return0;}constexpr bool b2=noexcept(f());// true, f() is a constant expression//constevalconstevalintsqr(intn){returnn*n;}constexprintr=sqr(100);// OKintx=100;intr2=sqr(x);// Error: Call does not produce a constantconstevalintsqrsqr(intn){returnsqr(sqr(n));// Not a constant expression at this point, but OK}constexprintdblsqr(intn){return2*sqr(n);// Error: Enclosing function is not consteval// and sqr(n) is not a constant}//constinitconstchar*g(){return"dynamic initialization";}constexprconstchar*f(bool p){returnp?"constant initializer":g();}constinitconstchar*c=f(true);// OK// constinit const char* d = f(false); // error

代码很简单,重点是对比一下。下面再看一个综合的应用:

#include<mutex>#include<string>intBASE_V=0;class Demo{public:// constexprstaticconstexprdoublePI=3.14;// constevaltemplate<typename T>constevalstaticTratioPI(T t){returnt*PI;}// constexpr-运行和编译期均可用template<typename T>constexprstaticTless(T min,T max){returnmin<max;}// consttemplate<typename T>staticconstauto&get(constT&t){returnBASE_V>t?BASE_V:1;}};class ControlMsg{public:voidaddmsg(conststd::string&msg){std::lock_guardlock(mutex_);msg_.append(msg);}private:std::string msg_="";std::mutex mutex_;};// constinitconstinit ControlMsg msg;// 使用示例intmain(){// 编译时constexprdoublenPI=Demo::ratioPI(3.0);static_assert(nPI>Demo::PI&&nPI<5*Demo::PI);// 运行时autostatus=Demo::less(3,5);//常量初始化msg.addmsg("Application started");return0;}

五、总结

有对比才有差距,才好掌握这四个关键字各自的特点和应用的场景。在实际应用的过程中,要根据实际情况来有针对性使用这些关键字。特别需要注意C++标准的版本不同的情况下,应用方式的不同。这样才能够编写出安全、高效的C++代码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 6:14:33

火灾烟雾早期预警:监控视频中识别异常烟雾形态

火灾烟雾早期预警&#xff1a;监控视频中识别异常烟雾形态 引言&#xff1a;从通用视觉理解到火灾风险的精准捕捉 在智慧城市与公共安全领域&#xff0c;早期火灾预警已成为智能监控系统的核心能力之一。传统的烟雾探测器依赖于物理传感器&#xff08;如光电、离子式&#xf…

作者头像 李华
网站建设 2026/5/1 4:16:49

万物识别数据闭环:自动收集反馈提升模型

万物识别数据闭环&#xff1a;如何自动收集用户反馈提升模型效果 作为一名AI产品经理&#xff0c;你是否遇到过这样的困境&#xff1a;上线了一个图像识别功能后&#xff0c;用户反馈识别结果不准确&#xff0c;却苦于没有高效的方法收集这些反馈来改进模型&#xff1f;本文将介…

作者头像 李华
网站建设 2026/5/3 8:31:58

计算机视觉竞赛捷径:快速部署基准模型抢占先机

计算机视觉竞赛捷径&#xff1a;快速部署基准模型抢占先机 万物识别-中文-通用领域&#xff1a;开启CV竞赛的“快车道” 在计算机视觉&#xff08;Computer Vision, CV&#xff09;竞赛中&#xff0c;时间就是优势。尤其是在比赛初期&#xff0c;快速构建一个可运行的基准模型&…

作者头像 李华
网站建设 2026/5/11 5:13:27

创业三年做到 2kw 营收

我是环界云计算机的创始人&#xff0c;新年又适合发表一下感悟了&#xff0c;其实三年做到 2kw 算速度很慢了&#xff0c;想起去年和 manus 创始人坐一起圆桌&#xff0c;今年人家就几十亿美金被 Meta 收购&#xff0c;感概这个世界变化太快了&#xff0c;人和人之间差距怎么这…

作者头像 李华
网站建设 2026/5/1 6:47:19

优化 .NET 项目中的网格显示

优化 .NET 项目中的网格显示 列跨度可均匀分配空间&#xff0c;使 .NET 网格能够干净利落地适应任何容器宽度&#xff0c;而无需手动调整大小。具有列跨列功能的数据网格可以配置为使列整体延伸以填充容器的整个宽度&#xff0c;从而消除网格边缘的未使用或空白区域。这种行为确…

作者头像 李华
网站建设 2026/5/11 3:47:00

当本科论文第一次被当作“学术起点”而非“毕业门槛”:一个不代写、不越界,却能帮你把课程作业思维升级为初步研究能力的AI协作者长什么样?

对大多数本科生而言&#xff0c;毕业论文是人生中第一次正式接触“研究”二字。但尴尬的是&#xff0c;很多人直到提交前一周&#xff0c;还在纠结&#xff1a;摘要怎么写&#xff1f;文献综述是不是就是摘抄&#xff1f;为什么导师总说“逻辑不顺”&#xff1f;甚至有人自嘲&a…

作者头像 李华