每日一个C++知识点|const 和 constexpr 的区别

在程序开发中,由于代码复杂度大或者程序员的疏忽,以及函数参数传递中的无意识修改,都会导致数据意外修改的风险。为了解决这个问题,出现了类型限定符。其中,C++的主要类型限定符是constconstexpr两种。

那么 const 和 constexpr 的区别和联系是什么呢?什么时候用哪一个呢?那么下面分别对这个问题进行解答~

const

早期的 C++ 是对 C 的扩展,而 C 语言中只能通过#define定义常量,比如#define MAX 100,但 #define 是预处理指令,没有类型检查,容易引发隐蔽错误。const 的出现填补了类型安全的只读常量的空白,既能保证数据只读,又能让编译器做类型校验,成为 C++ 的主要类型限定符。

const 作为 C++ 的类型限定符,使用非常广泛,可以修饰普通变量、指针、引用、函数参数、类成员变量、类成员函数、静态成员变量。下面分别对其用法进行举例:

const修饰普通变量

const 修饰普通变量后,变量初始化后不可修改。

const修饰指针

const修饰指针,精细控制只读范围,可以限制指针指向的内容只读,也可以限制指针本身只读,因此分为常量指针指针常量

常量指针:指向常量的指针,指向的内容不可以修改,但指针可以指向其他地方:

指针常量:指针本身是常量,指针指向的内容可以修改,但指针不能指向其他地方:

除此之外,还有一种指针本身和指向的内容都是只读的情况:

const 修饰引用

const 修饰引用,声明只读引用,避免通过引用修改原变量。

修饰参数也同此理~

只读引用可绑定常量,普通引用不行:

const 修饰类成员变量

const 类成员变量必须在构造函数初始化列表中初始化,不能在类内直接赋值,也不能在构造函数体中赋值。

const 修饰成员函数

const 修饰成员函数,保证函数不修改类成员,其语法是成员函数末尾加 const。

具体来说,是保证这个成员函数内部不能修改这个类的成员变量,如下图所示:

其中get_id是类的成员函数,score是类的成员变量。

const 修饰静态成员变量

const 修饰静态成员变量是类级别的只读常量,所有类实例共享这一个值,且值初始化后不可修改,具备 static 和 const 双重的属性,也就是共享只读的属性。

如果尝试修改:编译报错:

以上是 const 的各种使用场景,其核心是只读约束,不同场景的用法本质都是限定其修改权限。

那么我们下面来看看constexpr的用法。

constexpr

constexpr是 C++11 引入的关键字,是常量表达式,就是强制要求修饰的变量、 函数、构造函数能在编译期确定值。

因为const是运行时才限制可读属性,而constexpr是编译期就确定,所以是 const 的 “编译期增强版”。

这种做法的好处是把计算和对象构造提前到编译阶段完成,既提升运行效率,又解锁编译期专属的语法能力,还能提前暴露错误。

constexpr 主要修饰变量、函数、构造函数、类成员等场景,其用法如下:

constexpr修饰变量

constexpr修饰变量时必须用编译期可确定的值初始化,在限制可读方面比const更强,可直接用于数组大小、模板参数等需要编译期常量的场景。

constexpr 修饰函数

constexpr 函数并非必须编译期执行,而是支持编译期执行,只有传入编译期常量参数时,才会在编译期计算;传入运行期参数时,退化为普通函数:

这样做的好处是:既保留了编译期计算的性能优势,又不丧失普通函数的通用性,一份代码能同时满足编译期常量计算运行期动态计算两种场景,避免重复写两套逻辑。

但是编译器的 “自动判断” 可能带来行为不一致、调试难度增加、编译耗时上升等问题。

constexpr 修饰构造函数

constexpr修饰构造函数时,构造函数体必须为空,而且所有成员通过初始化列表初始化,在编译期构造对象;

其中类的成员变量需是 constexpr 兼容类型,比如int、float等。

#include<iostream>usingnamespacestd;classPoint{public:// constexpr 构造函数:编译期初始化成员constexprPoint(intx_,inty_):x(x_),y(y_){}// constexpr 成员函数:编译期获取成员值constexprintget_x()const{returnx;}constexprintget_y()const{returny;}private:intx,y;// 内置类型,支持 constexpr 初始化};intmain(){// 编译期创建 Point 对象constexprPointp(10,20);// 编译期获取成员值(无需运行期调用函数)constexprintx=p.get_x();// x=10constexprinty=p.get_y();// y=20cout<<"Point("<<x<<", "<<y<<")"<<endl;return0;}

constexpr 修饰静态成员变量

constexpr 修饰静态成员变量是 static const 的替代方案,属于类级别的编译期常量,所有实例共享,且不可修改。

不同的是,无需像 static const 那样做 “类内声明 + 类外初始化”

constexpr 最核心的用法是修饰变量和修饰函数,其中修饰变量是编译期常量,修饰函数支持编译期计算,大大提升运行效率。

二者区别

const 和 constexpr 的主要区别在于:const 是通用只读约束符,保证变量和数据初始化后不可修改,但不强制值在编译期确定。而 constexpr 是编译期常量强制符,不仅保证只读,还强制值和计算结果必须在编译期确定。

那么什么场景下用 const ,什么场景下用 constexpr 呢?

const 还是有一定的灵活性的,如用户输入、函数运行结果、类非静态只读成员等这些值需运行期确定,就只能用 const。

constexpr 胜在编译期强制约束,当希望函数和对象在编译期完成计算或者构造来提升运行效率时就用constexpr。

二者的联系

const 和 constexpr 都是为了约束数据的可修改性,提升代码安全性。

其中,constexpr 是 const 的超集,继承了 const 的"只读"特性,还额外增加了"编译期求值”的约束;编译期确定的值优先用 constexpr,仅需只读且值运行期确定时用 const,二者共同覆盖了 C++ 中所有"常量"场景。

总结

本文主要介绍 C++ 的关键字 const 和 constexpr 之间的区别和联系,可以概括为以下几点:

  1. const的作用和使用方法;
  2. constexpr的作用和使用方法;
  3. 仅需"只读"用const,需要"编译期确定值"用constexpr。

以上就是本文的内容,非常感谢您能花出宝贵的时间阅读,如果对您有帮助的话,欢迎点赞收藏~

如果本文存在不足之处甚至错误的地方欢迎大家在评论区多多批评指出, 我一定认真改正~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1150805.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是天猫国际品牌代理运营?一般代运营提供哪些服务?

在全球化电商浪潮的推动下&#xff0c;天猫国际平台成为众多海外品牌进入中国市场的重要通道。然而&#xff0c;海外品牌在进入中国市场时&#xff0c;往往面临着文化差异、运营规则不熟悉、市场推广困难等诸多挑战。天猫国际品牌代理运营作为一种专业的电商服务模式&#xff0…

screen命令在断网环境下的调试应用操作指南

断网不断程&#xff1a;用screen构建高可用远程调试环境你有没有过这样的经历&#xff1f;深夜正在远程烧录固件&#xff0c;眼看着进度条走到 90%&#xff0c;突然 Wi-Fi 切换、4G 信号丢失&#xff0c;SSH 连接一断&#xff0c;终端里的任务瞬间“消失”。刷新会话后发现&…

[特殊字符]_Web框架性能终极对决:谁才是真正的速度王者[20260112172541]

作为一名拥有10年开发经验的全栈工程师&#xff0c;我经历过无数Web框架的兴衰更替。从早期的jQuery时代到现在的Rust高性能框架&#xff0c;我见证了Web开发技术的飞速发展。今天我要分享一个让我震惊的性能对比测试&#xff0c;这个测试结果彻底改变了我对Web框架性能的认知。…

超详细版LVGL教程:从零实现家居主界面

从零打造一个智能家居主界面&#xff1a;LVGL实战全记录最近在做一个家庭中控屏的项目&#xff0c;客户想要一块能控制全屋灯光、空调和安防系统的触摸面板。这事儿听起来简单&#xff0c;但真上手才发现——图形界面这东西&#xff0c;不光是“画几个按钮”那么简单。尤其是用…

深耕香港会计服务领域 香港卓信会计打造企业注册一站式解决方案

作为连接内地与国际市场的核心枢纽&#xff0c;香港凭借国际化金融环境与规范化商业体系&#xff0c;成为企业出海布局的重要据点。在此背景下&#xff0c;深耕香港财税服务领域的卓信会计服务有限公司&#xff08;ZHUOXIN ACCOUNTING SERVICE LIMITED&#xff09;凭借扎实的合…

RealMem: 重新定义AI的“长期记忆”,挑战真实场景交互

AI Agent 真的准备好成为你的长期合作伙伴了吗&#xff1f;你有没有这样的经历&#xff1a;在使用chatgpt等AI Assistant时&#xff0c;不断进行这两种动作&#xff1a;“新建聊天页”和“寻找过去的某个聊天页继续问”。为什么需要新建聊天页&#xff1f;因为一个会话上下文太…

天猫TP公司是什么意思?一般提供哪些服务?

在电商行业的发展进程中&#xff0c;天猫平台作为国内领先的电商巨头&#xff0c;吸引了众多品牌和商家的入驻。为了帮助品牌方更好地运营天猫店铺&#xff0c;提高店铺的竞争力和业绩&#xff0c;天猫TP公司应运而生。天猫TP公司凭借其专业的运营能力和丰富的资源优势&#xf…

手把手教程:Elasticsearch下载与Logstash环境搭建

从零搭建日志处理流水线&#xff1a;Elasticsearch 安装与 Logstash 配置实战 你有没有遇到过这样的场景&#xff1f;线上服务突然报错&#xff0c;几十台服务器的日志分散在各个角落&#xff0c;翻查起来像大海捞针。运维人员熬夜 grep 文件、开发团队反复复现问题——这背后…

MDK与工业自动化集成:系统学习手册

MDK与工业自动化集成&#xff1a;从代码到产线的实战指南你有没有遇到过这样的场景&#xff1f;一个工业控制项目&#xff0c;团队里有人写MCU固件&#xff0c;有人做上位机通信&#xff0c;还有人负责PLC逻辑。结果到最后联调时&#xff0c;发现采样周期对不上、Modbus寄存器偏…

【AI机器视觉】MediaPile和YOLO对比

MediaPipe 是 Google 开源的一个用于构建实时多媒体机器学习应用的框架。它的强大之处在于&#xff0c;将复杂的机器学习模型&#xff08;如手部关键点检测、人体姿态估计、人脸网格识别等&#xff09;封装成了简单易用的 API&#xff0c;支持多语言多平台&#xff0c;让开发者…

解析USB3.0接口定义引脚说明中的盲埋孔使用技巧

从USB3.0引脚定义看高速PCB设计&#xff1a;盲埋孔为何是信号完整性的“隐形推手”&#xff1f;你有没有遇到过这样的情况&#xff1f;明明严格按照USB3.0规范布线&#xff0c;差分对也做了等长匹配&#xff0c;参考平面也没分割——可测试时眼图就是打不开&#xff0c;误码率居…

Java Web 智能物流管理系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着电子商务和全球化贸易的快速发展&#xff0c;物流行业在供应链管理中的重要性日益凸显。传统物流管理系统存在信息孤岛、效率低下、数据实时性差等问题&#xff0c;难以满足现代企业对智能化、高效化物流管理的需求。智能物流管理系统通过整合物流资源、优化配送路径、…

[特殊字符]_高并发场景下的框架选择:从性能数据看技术决策[20260112170745]

作为一名经历过无数生产环境考验的资深工程师&#xff0c;我深知在高并发场景下选择合适的技术栈是多么重要。最近我参与了一个日活千万级的电商平台重构项目&#xff0c;这个项目让我重新思考了Web框架在高并发环境下的表现。今天我要分享的是基于真实生产数据的框架性能分析&…

USB3.0接口引脚定义详解:从基础到应用完整指南

USB3.0引脚设计全解析&#xff1a;从物理连接到高速通信的底层逻辑你有没有遇到过这样的情况&#xff1f;插上一个USB3.0移动硬盘&#xff0c;理论速度应该轻松突破400MB/s&#xff0c;结果拷贝大文件时却只有几十兆——慢得像在用十年前的老设备。问题很可能不在硬盘本身&…

Elasticsearch客户端集成:应用层对接实战案例

Elasticsearch客户端集成实战&#xff1a;从连接到高可用的全链路设计最近在重构公司日志平台时&#xff0c;又一次深度踩进了Elasticsearch 客户端集成的“坑”。虽然 ES 本身功能强大&#xff0c;但真正让系统稳定跑起来的&#xff0c;其实是应用层那个看似简单的es客户端。用…

微服务分布式SpringBoot+Vue+Springcloud人口老龄化社区活动老年人服务和管理平台

目录摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 随着人口老龄化趋势加剧&#xff0c;社区养老服务需求日益增长。传统服务模式存在效率低、资源分散、信息孤岛等问题&#xff0c;亟需通过数字化手段优化管理流程。…

Java Web 电影评论网站系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着互联网技术的快速发展和数字化娱乐的普及&#xff0c;电影评论网站逐渐成为观众分享观影体验、交流观点的重要平台。传统的电影评论系统在功能扩展性、用户体验以及数据处理效率方面存在诸多不足&#xff0c;难以满足现代用户对互动性和实时性的需求。因此&#xff0c…

UDS多帧传输与流控策略在车内通信的应用

UDS多帧传输与流控策略&#xff1a;如何让车载通信“既快又稳”&#xff1f;你有没有想过&#xff0c;一辆智能汽车在做OTA升级时&#xff0c;成千上万字节的固件数据是怎么通过一根带宽只有500kbps的CAN总线安全送达ECU的&#xff1f;更神奇的是&#xff0c;为什么低端MCU不会…

Day 28:【99天精通Python】HTML解析库 BeautifulSoup - 像喝汤一样提取网页数据

Day 28&#xff1a;【99天精通Python】HTML解析库 BeautifulSoup - 像喝汤一样提取网页数据 前言 欢迎来到第28天&#xff01; 在昨天的课程中&#xff0c;我们学会了用 requests 库把网页源代码&#xff08;HTML&#xff09;下载下来。但是&#xff0c;打印出来的 response…

微服务分布式SpringBoot+Vue+Springcloud人脸识别的微信小程序的学生选课签到定位考勤系统

目录摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 该系统基于微服务分布式架构&#xff0c;结合SpringBoot、Vue和SpringCloud技术栈&#xff0c;实现了一套集成人脸识别、微信小程序交互、学生选课及签到定位考勤功…