当前位置: 首页 > news >正文

c++的const

const在C++中是一个非常重要的关键字,用于定义不可变的变量、函数参数、成员函数等。它可以提高代码的可读性、安全性,并帮助编译器进行优化。

  1. 定义常量

使用const定义不可变的变量:

const int MAX_SIZE = 100;
  1. 常量指针

指向常量的指针和常量指针有不同的用法:

const int* ptr1 = &MAX_SIZE; // 指向常量的指针
int* const ptr2 = &variable; // 常量指针
const int* const ptr3 = &MAX_SIZE; // 指向常量的常量指针
  1. 常量引用

常量引用用于避免不必要的复制,并且保证引用的值不会被修改:

void printValue(const int& value) {std::cout << value << std::endl;
}
  1. 常量成员函数

在类中,常量成员函数保证不会修改对象的成员变量:

class MyClass {
public:int getValue() const {return value;}private:int value;
};
  1. 常量对象

定义一个常量对象,这个对象只能调用其常量成员函数:

const MyClass obj;
obj.getValue();
  1. 常量成员变量

在类中定义常量成员变量,这些变量必须在构造函数的初始化列表中初始化:

class MyClass {
public:MyClass(int v) : value(v) {}const int value;
};
  1. 常量静态成员变量

常量静态成员变量在类中定义,但必须在类外初始化:

class MyClass {
public:static const int MAX_VALUE;
};const int MyClass::MAX_VALUE = 100;
  1. 常量函数参数

使用const修饰函数参数,表示参数在函数内部不会被修改:

void process(const int value) {// value 不能被修改
}
  1. 返回常量引用

返回常量引用以避免返回值被修改:

const std::string& getName() const {return name;
}
  1. 常量迭代器

使用常量迭代器来遍历容器,确保元素不会被修改:

std::vector<int> vec = {1, 2, 3, 4};
for (std::vector<int>::const_iterator it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << std::endl;
}
  1. constexpr

constexpr在C++11中引入,用于定义在编译时计算的常量:

constexpr int getValue() {return 42;
}
constexpr int value = getValue();
  1. const_cast

const_cast用于移除或添加const属性,但应谨慎使用,避免违反常量性:

void modify(const int& value) {int& nonConstValue = const_cast<int&>(value);nonConstValue = 100;
}

这是一个名为modify的函数,它接受一个常量引用类型的整数参数value。

在C++中,常量引用(const reference)是对一个常量的引用。使用常量引用的主要目的是防止引用的对象被修改,同时允许该对象通过引用的方式传递,以避免复制大的对象。常量引用主要用于函数参数和返回值。

常量引用的语法

常量引用的语法如下:

const int& ref = someInt;

在这个例子中,ref是一个对整数someInt的常量引用。通过ref,可以读取someInt的值,但不能修改它。

使用常量引用的优点

  1. 防止修改:通过常量引用,可以确保函数不会修改传递给它的对象。例如:
    void printValue(const int& value) {
    std::cout << value << std::endl;
    // value = 10; // 这行代码将导致编译错误
    }

  2. 效率:常量引用可以避免对象的复制,尤其是对于大对象或自定义类型。通过引用传递而不是通过值传递,可以节省内存和时间。例如:
    void processLargeObject(const LargeObject& obj) {
    // 处理 obj 而不复制它
    }

  3. 兼容性:常量引用可以绑定到非常量对象和临时对象,因此使用常量引用可以使函数更加通用。例如:
    void showValue(const int& value) {
    std::cout << value << std::endl;
    }

    int main() {int a = 5;const int b = 10;showValue(a); // 绑定到非常量对象showValue(b); // 绑定到常量对象showValue(15); // 绑定到临时对象
    }
    

常量引用的限制

  1. 不可修改:通过常量引用,无法修改引用的对象。如果需要修改对象,则不能使用常量引用。
  2. 不能绑定到非常量指针:常量引用不能绑定到非常量指针,但可以绑定到非常量对象。

在C++中,int& value 和 int &value 实际上是完全相同的。两者都是对整数类型的引用,并且语法上没有区别。这种不同的书写方式只是个人编码风格的差异。更详细地解释一下。

引用的基本概念

引用(reference)是C++中的一种变量类型,允许创建对另一个变量的别名。定义一个引用时,使用&符号。例如:

int a = 10;
int& ref = a;

在这个例子中,ref是一个对整数变量a的引用,ref和a指向同一个内存位置,对ref的操作实际上是对a的操作。

不同书写方式的对比

int& value

int& value = someVariable;

这种方式将&符号紧贴在类型int上,表示value是一个整数引用。很多程序员喜欢这种写法,因为它清楚地表明了value的类型是“引用”。

int &value

int &value = someVariable;

这种方式将&符号紧贴在变量名value上,这在视觉上让人觉得&是变量名的一部分。有些程序员更喜欢这种风格,因为他们认为它更直观。

编译器的处理

无论使用哪种风格,编译器都会以相同的方式处理它们。int& value 和 int &value 都表示一个对整数类型的引用,二者之间没有任何功能上的差异。以下两个例子是完全等价的:

int a = 10;
int& ref1 = a;  // 引用声明方式1
int &ref2 = a;  // 引用声明方式2ref1 = 20;
std::cout << a << std::endl;  // 输出20
ref2 = 30;
std::cout << a << std::endl;  // 输出30

综合实例

下面是一个综合使用const的例子:

#include <iostream>
#include <vector>class MyClass {
public:MyClass(int v) : value(v) {}int getValue() const {return value;}const std::vector<int>& getValues() const {return values;}void addValue(const int& v) {values.push_back(v);}private:const int value;std::vector<int> values;
};int main() {const MyClass obj(10);std::cout << obj.getValue() << std::endl;obj.addValue(1); // 常量对象调用非常量成员函数是允许的,因为非常量成员函数不修改常量成员变量const std::vector<int>& values = obj.getValues();for (std::vector<int>::const_iterator it = values.begin(); it != values.end(); ++it) {std::cout << *it << std::endl;}return 0;
}

在这个综合实例中,展示了如何在类中使用const关键字来定义常量成员变量、常量成员函数、常量参数和常量引用。通过这些实践,可以编写出更加健壮和高效的C++代码。

相关文章:

c++的const

const在C中是一个非常重要的关键字&#xff0c;用于定义不可变的变量、函数参数、成员函数等。它可以提高代码的可读性、安全性&#xff0c;并帮助编译器进行优化。 定义常量 使用const定义不可变的变量&#xff1a; const int MAX_SIZE 100;常量指针 指向常量的指针和常量…...

Git不想跟踪某个文件

如果你不想跟踪某个文件&#xff0c;可以将该文件路径添加到 .gitignore 文件中。.gitignore 文件用于告诉 Git 哪些文件或目录应该被忽略&#xff0c;不进行版本控制。以下是具体步骤&#xff1a; 编辑 .gitignore 文件&#xff1a;在项目的根目录下找到或创建一个 .gitignore…...

DB-GPT 文档切分报错

感谢阅读 配置完知识库&#xff0c;进行切分报错切分完成后&#xff0c;进行问答时后台日志报错 配置完知识库&#xff0c;进行切分报错 报的错如下 document sync error cryptography>3.1 is required for AES algorithm pip install -U cryptography 之后重新运行程序 …...

#如何使用 Qt 5.6 在 Android 上启用 NFC

如何使用 Qt 5.6 在 Android 上启用 NFC NFC 技术在 Android 应用开发中变得越来越重要。在本文中&#xff0c;我将介绍如何使用 Qt 5.6 来实现 Android 上的 NFC 功能。这个教程基于一个创建于 8 年 8 个月前的问题&#xff0c;并在 7 年 3 个月前进行了修改&#xff0c;讨论…...

合并排序的数组

题目链接 合并排序的数组 题目描述 注意点 A的末端有足够的缓冲空间容纳BA和B都是排序的 解答思路 最初想到的是双指针&#xff0c;从小到大找到合并B时应该A相应位置应该插入的元素&#xff0c;因为在插入的过程中B的元素会替换A原有位置的元素&#xff0c;所以需要先将A…...

js 复制文本带样式

一键复制带样式的html文本到邮件 <div><div idcopy-content><div style{{ fontSize: 16px,fontWeight: 500, lineHeight: 24px, color: #222, marginBottom: 16px }}>邀请您参加腾讯会议网络研讨会&#xff08;Webinar)</div></div><Button …...

服务器之BIOS基础知识总结

1.BIOS是什么&#xff1f; BIOS全称Basic Input Output System&#xff0c;即基本输入输出系统&#xff0c;是固化在服务器主板的专用ROM上&#xff0c;加载在服务器硬件系统上最基本的运行程序&#xff0c;它位于服务器硬件和OS之间&#xff0c;在服务器启动过程中首先运行&am…...

FFmpeg 实现从摄像头获取流并通过RTMP推流

使用FFmpeg库实现从USB摄像头获取流并通过RTMP推流&#xff0c;FFmpeg版本为4.4.2-0。RTMP服务器使用的是SRS&#xff0c;拉流端使用VLC。 在Linux上查看摄像头信息可使用 v4l2-ctl 工具&#xff0c;查看命令如下&#xff1a; v4l2-ctl --device/dev/video0 --list-formats-e…...

学生管理系统

一、登录 用户类&#xff1a;属性&#xff1a;用户名、密码、身份证号码、手机号码 1、欢迎页面 System.out.println("欢迎来到学生管理系统"); System.out.println("请选择操作1登录 2注册 3忘记密码"); 代码实现&#xff1a; //欢迎页面public static…...

【linux】网络基础(3)——tcp协议

文章目录 TCP协议概括TCP头部格式TCP连接管理建立连接&#xff08;三次握手&#xff09;数据传输确认应答机制捎带应答 滑动窗口丢包问题 拥塞控制延时应达 终止连接&#xff08;四次挥手&#xff09; TCP协议概括 TCP是一个面向连接的协议&#xff0c;在传输数据之前需要建立连…...

[Day 21] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

區塊鏈的智能合約運行機制 區塊鏈技術自比特幣誕生以來&#xff0c;便以其去中心化、安全性和透明性等特點引起了廣泛的關注和應用。而智能合約作為區塊鏈技術的一大創新&#xff0c;進一步擴展了區塊鏈的應用場景&#xff0c;使其不僅僅局限於數字貨幣&#xff0c;還可以應用…...

使用ps给gif动图抠图

目录 导入gif图片 打开时间轴 选择图片 魔棒抠图-初步抠图 套索抠图-精准抠图 导入gif图片 打开时间轴 因为gif动图实际上多张图片实现的效果&#xff0c;所以如果要给gif抠图&#xff0c;就得挨个给每个时间线的图片抠图 点击窗口->时间轴 选择图片 在时间轴上选择要…...

pmp顺利通关总结

目录 一、背景二、总结三、过程 一、背景 人活着总是想去做一些事情&#xff0c;通过这些事情来证明自己还活着。 而我证明自己还会活着并且活得很好的方式和途径&#xff0c;是通过这些东西去让自己有一个明确的边界节点&#xff1b;借此知识来验证自己的学习能力。 我坚定认…...

未来的钥匙在于过去:学历史的真正意义,震惊!历史竟然是偶然的?从历史中寻找未来的方向!

我们自幼接受的教育是&#xff0c;学历史是为了相信历史是必然的。中国人民必然战胜日寇的侵略&#xff0c;解放思想和改革开放必定会发生&#xff0c;和平和发展必定是世界的主题&#xff0c;中国经济必定是高速增长…… 然而&#xff0c;在真正的历史学家眼中&#xff0c;历史…...

ES6自定义模块

在ES6中&#xff0c;我们可以使用 export 和 import 关键字来定义和使用自定义模块。 定义模块 导出&#xff08;export&#xff09; 命名导出&#xff08;Named Exports&#xff09;&#xff1a; 使用 export 关键字来导出模块中的变量、函数、类等。例如&#xff1a; // ma…...

Windows页面错误(Page Fault)写几种c++会导致,此问题的例子

在C中&#xff0c;直接导致Windows页面错误&#xff08;Page Fault&#xff09;的情景较少直接由编程错误引发&#xff0c;页面错误更多是由操作系统在内存管理和虚拟内存机制中处理的。不过&#xff0c;某些编程错误可能导致访问违规&#xff0c;进而间接引起操作系统报告页面…...

AC7801时钟配置流程

一 默认配置 在启动文件中&#xff0c;已经对时钟进行了初始化&#xff0c;默认按外部8M晶振&#xff0c;配置系统时钟为48MHZ&#xff0c;APB为系统时钟的2分频&#xff0c;为24MHZ。在system_ac780x.c文件中&#xff0c;可以找到下面这个系统初始化函数&#xff0c;里面有Se…...

加密与安全_Java 加密体系 (JCA) 和 常用的开源密码库

文章目录 Java Cryptography Architecture (JCA)开源国密库国密算法对称加密&#xff08;DES/AES⇒SM4&#xff09;非对称加密&#xff08;RSA/ECC⇒SM2&#xff09;散列(摘要/哈希)算法&#xff08;MD5/SHA⇒SM3&#xff09; 在线生成公钥私钥对&#xff0c;RSA公私钥生成参考…...

读书笔记-《Spring技术内幕》(三)MVC与Web环境

前面我们学习了 Spring 最核心的 IoC 与 AOP 模块&#xff08;读书笔记-《Spring技术内幕》&#xff08;一&#xff09;IoC容器的实现、读书笔记-《Spring技术内幕》&#xff08;二&#xff09;AOP的实现&#xff09;&#xff0c;接下来继续学习 MVC&#xff0c;其同样也是经典…...

k8s及常用对象简介

文章目录 一、k8s是什么应用程序早期部署形式容器的引入k8s的作用 二、k8s中的常用对象1、Node获取node信息 2、Namespacenamespace的使用 3、Pod生命周期pod的使用 4、DaemonSetDaemonSet的使用 5、Deployment创建deploy 6、ReplicaSet7、StatefulSet创建StatefulSet 8、更新操…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...