[C++关键字] const/constexpr
文章目录
- const/constexpr[^1]
- const 与 宏
- const 与 类
- const 与 指针
- const 其他
- constexpr (C++11之后)
- reference
const/constexpr1
- 尽可能的使用constexpr
- 对于不变的变量,尽量用const修饰
const 与 宏
- const vs define的比较:define只是字符的替换,没有类型方面的约束,而const修饰的变量可以防止窜改与保持类型安全。 所以一般推荐多用const定义常量而不是用宏。
- const修饰变量必须初始化,表示常量则不可改变,没有初始化则没有意义;知乎博文描述:const放在data只读区域,不过也不是绝对的,有的时间统计优化等级开的高,也不取地址,可能会优化成立即数在.text段中。
const 与 类
- 1. 修饰类变量-对象:则只能调用const 函数, 不能调用非const函数; 除非在成员变量前面添加mutable 显性指明可变。
- 2. 修饰类中成员变量:必须在初始化列表中进行初始化
- 3. 静态常量和普通常量类似: 推荐放到类外,在相应的.cc/.cpp源文件中进行初始化
- 4. 修饰成员函数:表示函数中成员变量不可被改变,可以被const 对象调用,也可以被普通对象调用;但是这种函数中不能调用非const类型的函数。
// test.h
class Test {public:Test(int var): const_var_(var) {} // 2. 修饰类中成员变量const int GetVarible() const { return const_var_;} // 4. 修饰成员函数void SetVariable(int var) { mutable_var_ = var; }mutable int mutable_var_;static const int static_const_var_; // 3. 静态常量和普通常量类似private:const int const_var_; // 2. 修饰类中成员变量
};// test.cc
static const int Test::static_const_var_ = 0;const Test test(0); // 1. 修饰类变量-对象
test.GetValue(); // 1. 修饰类变量-对象
test.mutable_var_ = 200;
const 与 指针
- 1. 指针常量:指向的内容是常量,内容不可变,但是指针可变
- 2. 常量指针:指针为常量,指针不可变,但是内容可变
- 3. 常量指针常量:指针和内容都是常量,都不可变
- 区分哪个是常量的记忆秘诀:const 离哪个量近就是修饰哪个, 如下所示,var_1,var_2 就是const与char类型近,所以常量是对char类型的,也就是内容来约定的; 而var_3是 const与 var_3近,又因为var_3是 指针变量,所以const修饰的是指针。
const char * var_1; // 1. 指针常量
char const * var_2; // 1. 指针常量
char * const var_3; // 2. 常量指针
const char * const var_4; // 3. 常量指针常量
const 其他
- const 与 引用: 内容不可更改,且没有copy开销。 一般参数传递时推荐的写法。
- const 转换: 非const转const 很方便;但是const 转非const也就是remove const是麻烦的,一般不支持隐式转换。可以考虑用remove_const,推荐使用const_cast来实现。
// 注意用模板的机制,实现remove const操作
template<typename T>
struct remove_const
{typedef T Type;
};template<typename T>
struct remove_const<const T> // 点睛之笔
{typedef T Type;
};template<typename T>
using RemoveConstT = typename remove_const<T>::Type;
- 顶层const: 修饰的对象本身不能改变,如const变量,指针常量等
- 底层const:修饰的指针或者引用的对象不能改变, 本身可以改变,但是所指内容不可以改变,如 常量指针。 这种const只能用const_cast<>方式移除,但是有风险。
constexpr (C++11之后)
【在编译期间就能完成执行的代码就最好改为constexpr描述, 这样能提升运气期间的性能,因为编译期间已经确定了表达式的值,不用在运行期间再执行表达式】所以尽可能的使用constexpr
- 修饰表达式:如果一个常量表达式能在编译阶段确定,那么就需要设置为constexpr, 另外如果我们想让一个表达式在编译期间就能得到值,那么我们也需要设置成constexpr。把它放到变量定义前,那么用来初始化这个变量的表达式「必须」是常量表达式。
- 修饰对象: 对象是const的,对象需要编译期间确定。
- 修饰函数:如果不能在编译时期计算出来,那么constexpr修饰的函数就和普通函数一样了, 如果能就是一个const 常量存于代码中,用于运行时使用。
- 检测constexpr函数是否产生编译时期值的方法很简单:就是利用std::array需要编译期常值才能编译通过的小技巧。这样的话,即可检测你所写的函数是否真的产生编译期常值了。
- constexpr与virtual功能上正好相反
constexpr int GetNumber() {...}const int num = GetNumber(); // 如果GetNumber是个模板递归,那么需要在编译期间确定值,那么就需要将const改为constexpr
constexpr int num = GetNumber(); // 则编译期间能确定num的值
- 在实际规范地使用用时,一般把能在编译期确定的表达式或函数定义为constexpr,且变量名kVariable方式定义表示一种常量。而运行期间的定义为const。
reference
参考知乎博文 ↩︎
相关文章:
[C++关键字] const/constexpr
文章目录const/constexpr[^1]const 与 宏const 与 类const 与 指针const 其他constexpr (C11之后)referenceconst/constexpr1 尽可能的使用constexpr对于不变的变量,尽量用const修饰 const 与 宏 const vs define的比较:define只是字符的替换…...
FPGA电源电流参数
一、FPGA里各个电源释义 VCCINT VCCINT是FPGA芯片的内核电压,是用来给FPGA内部的逻辑门和触发器上的电压。即芯片的晶体管开关是有核心电压提供。当内部逻辑工作时钟速率越高,使用逻辑资源越多,则核心电压供电电流会更大,可高达几…...
【Git】Git下载安装与使用(一)
目录 1. 前言 1.1 什么是Git 1.2 使用Git能做什么 2. Git概述 2.1 Git简介 2.2 Git下载与安装 3. Git代码托管服务 3.1 常用的Git代码托管服务 3.2 码云代码托管服务 1. 前言 1.1 什么是Git Git是一个分布式版本控制工具,主要用于管理开发过程中的源代码…...
刷题记录:牛客NC20545[HEOI2012]采花
传送门:牛客 题目描述: 题目较长,此处暂略 输入: 5 3 5 1 2 2 3 1 1 5 1 2 2 2 2 3 3 5 输出: 2 0 0 1 0总结一下题意,就是求区间[l,r][l,r][l,r]出现次数大于1的花的种类数. 考虑使用主席树或者离线树状数组的方法来解决.由于数据加强的原因,导致主席树在本题中是不能完美通…...
每日学术速递2.21
CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.T2I-Adapter: Learning Adapters to Dig out More Controllable Ability for Text-to-Image Diffusion Models 标题:T2I-Adapter:学习Adapter,为…...
网络安全之认识挖矿木马
一、什么是挖矿木马? 比特币是以区块链技术为基础的虚拟加密货币,比特币具有匿名性和难以追踪的特点,经过十余年的发展,已成为网络黑产最爱使用的交易媒介。大多数勒索病毒在加密受害者数据后,会勒索代价高昂的比特币…...
OpenCV实战——基于分水岭算法的图像分割
OpenCV实战——基于分水岭算法的图像分割0. 前言1. 分水岭算法2. 分水岭算法直观理解3. 完整代码相关链接0. 前言 分水岭变换是一种流行的图像处理算法,用于快速将图像分割成同质区域。分水岭变换主要基于以下思想:当图像被视为拓扑浮雕时,均…...
YOLOv8模型调试记录
前言 新年伊始,ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本,目前支持图像分类、物体检测和实例分割任务,在还没有开源时就收到了用户的广泛关注。 值得一提的是,在博主的印象中,YOLO系…...
算法刷题打卡第97天:删除字符串两端相同字符后的最短长度
删除字符串两端相同字符后的最短长度 难度:中等 给你一个只包含字符 a,b 和 c 的字符串 s ,你可以执行下面这个操作(5 个步骤)任意次: 选择字符串 s 一个 非空 的前缀,这个前缀的所有字符都相…...
WebGPU学习(3)---使用IndexBuffer(索引缓冲区)
现在让我们将 IndexBuffer 与 VertexBuffer 一起使用。演示示例 1.准备索引数据 我们用 Uint16Array 类型来准备索引数据。我们将矩形的4个点放到 VertexBuffer 中,然后根据三角形绘制顺序,组织成 0–1–2 和 0–2–3 的结构。 const quadIndexArray …...
Java代码加密混淆工具有哪些?
在Java中,代码加密混淆工具可以帮助开发者将源代码进行加密和混淆处理,以增加代码的安全性和保护知识产权。以下是一些流行的Java代码加密混淆工具: 第一款:ProGuard:ProGuard ProGuard:ProGuard…...
华为OD机试 - 高效的任务规划(Python) | 机试题+算法思路+考点+代码解析 【2023】
高效的任务规划 题目 你有 n 台机器编号为1-n,每台都需要完成一项工作, 机器经过配置后都能独立完成一项工作。 假设第i台机器你需要花 Bi 分钟进行设置, 然后开始运行,Ji分钟后完成任务。 现在,你需要选择布置工作的顺序,使得用最短的时间完成所有工作。 注意,不能同…...
ChatGPT写程序如何?
前言ChatGPT最近挺火的,据说还能写程序,感到有些惊讶。于是在使用ChatGPT有一周左右后,分享一下用它写程序的效果如何。1、对于矩阵,把减法操作转换加法?感觉不错的,能清晰介绍原理,然后写示例程…...
编译链接实战(9)elf符号表
文章目录符号的概念符号表探索前面介绍了elf文件的两种视图,以及两种视图的各自几个组成部分:elf文件有两种视图,链接视图和执行视图。在链接视图里,elf文件被划分成了elf 头、节头表、若干的节(section)&a…...
React合成事件的原理是什么
事件介绍 什么是事件? 事件是在编程时系统内发生的动作或者发生的事情,而开发者可以某种方式对事件做出回应,而这里有几个先决条件 事件对象 给事件对象注册事件,当事件被触发后需要做什么 事件触发 举个例子 在机场等待检票…...
Arduino-交通灯
LED交通灯实验实验器件:■ 红色LED灯:1 个■ 黄色LED灯:1 个■ 绿色LED灯:1 个■ 220欧电阻:3 个■ 面包板:1 个■ 多彩杜邦线:若干实验连线1.将3个发光二极管插入面包板,2.用杜邦线…...
【论文笔记】Manhattan-SDF == ZJU == CVPR‘2022 Oral
Neural 3D Scene Reconstruction with the Manhattan-world Assumption 本文工作:基于曼哈顿世界假设,重建室内场景三维模型。 1.1 曼哈顿世界假设 参考阅读文献:Structure-SLAM: Low-Drift Monocular SLAM in Indoor EnvironmentsIEEE IR…...
好消息!Ellab(易来博)官方微信公众号开通了!携虹科提供专业验证和监测解决方案
自1949年以来,丹麦Ellab一直通过全球范围内的验证和监测解决方案,协助全球生命科学和食品公司优化和改进其流程的质量。Ellab全面的无线数据记录仪,热电偶系统,无线环境监测系统,校准设备,软件解决方案等等…...
想要去字节跳动面试Android岗,给你这些面试知识点
关于面试字节跳动,我总结一些面试点,希望可以帮到更多的小伙伴,由于篇幅问题这里没有把全部的面试知识点问题都放上来!!目录:1.网络2.Java 基础&容器&同步&设计模式3.Java 虚拟机&内存结构…...
Java的Lambda表达式的使用
Lambda表达式是Java 8中引入的一个重要特性,它是一种简洁而强大的语法结构,可以用于替代传统的匿名内部类。 Lambda表达式的语法结构如下: (parameters) -> expression或者 (parameters) -> { statements; }其中,paramet…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
Android屏幕刷新率与FPS(Frames Per Second) 120hz
Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数,单位是赫兹(Hz)。 60Hz 屏幕:每秒刷新 60 次,每次刷新间隔约 16.67ms 90Hz 屏幕:每秒刷新 90 次,…...
