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

【C++】const与类(const修饰函数的三种位置)

目录

const基本介绍

正文

前:

中:

后:

拷贝构造使用const


目录

const基本介绍

正文

前:

中:

后:

拷贝构造使用const


const基本介绍

const 是 C++ 中的修饰符,用于声明常量或表示不可修改的对象、函数或成员函数。

我们已经了解了const基本用法,我们先进行简单的回顾:

  1. 声明常量变量:使用 const 关键字来声明常量,一旦声明为常量,其值就不能被修改。例如:

     const int MAX_VALUE = 100;
  2. const修饰指针:

    a).const 修饰指针所指向的值不可被修改:

 int x = 5;const int* ptr = &x;*ptr = 10; // 错误:试图修改 const 指针所指向的值​int y = 10;ptr = &y; // 正确:const 指针本身可以被修改,指向不同的地址

b).const 修饰指针本身不可被修改:

 int x = 5;int* const ptr = &x;ptr = nullptr; // 错误:试图修改 const 指针本身的值​int y = 10;*ptr = y; // 正确:可以通过 const 指针修改指向的值

const修饰指针具体讲解:C语言:const函数修饰指针_const函数指针-CSDN博客

3.声明常量引用:使用 const 关键字修饰引用,表示引用的值不能被修改。例如:

 const int& ref = someVariable;

错误例子如下:

 int x = 5;const int& ref = x;ref = 10; // 错误:试图修改 const 引用的值

正文

 const char &getCharRef(const SomeClass &param) const{// 返回一个 const char& 类型的常量引用return someChar;}声明一个名为 constCharRef 的函数,该函数接收一个 const 类型的参数,并返回一个 const char& 类型的常量引用。同时,这个函数本身也是一个 const 成员函数示例中 MyClass 是一个类名,SomeClass 是作为参数传递给函数的某个类型,someChar 是一个 const 类型的字符变量、字符串字面值或者对象中的成员变量

看以上代码,在三个位置(文中称做前中后)都用const进行了修饰,那这三个点具体意义是什么呢?

前:

该const是修饰返回值类型

 const int getVal() {// 在这里实现函数的逻辑someVal = 10; // 修改对象中的成员变量return someVal;}

const 关键字用于修饰函数返回值前面的类型,表示函数返回的是一个常量值。这意味着,一旦 getVal() 函数返回一个常量值之后,返回的值就不能被修改,否则编译器会报错。

此处的 const 关键字并没有修饰函数本身。因此,即使在函数内部修改了对象中的成员变量,函数返回的仍然是一个常量值,不能被修改

中:

 void Add(const int val, const int constant){int result = val + constant;cout << "Result: " << result << endl;}

声明常量参数,该const则是为了保护数据,防止val和constant的值被修改

后:

声明常量成员函数:在类中声明成员函数时,使用 const 关键字修饰函数,表示该函数不会修改类的成员变量。该函数不会修改被隐式访问的对象,只能访问类的常量成员变量或调用其他常量成员函数

 class MyClass{public:int getValue() const;​private:int value;};​int MyClass::getValue() const{return value; // 只能读取成员变量的值}const char& operator[](size_t pos) const {assert(pos < _size);return _str[pos];}

函数声明中的 const 关键字修饰的是 this 指针,即表示该成员函数对应的实例对象在函数内部是只读的,不能修改对象的成员变量。因此,即使在函数内部尝试修改 _str 字符串,编译器也不会报错,但这样的操作违反了 const 限定的约定,也会导致代码运行时出现不可预期的问题。

  1. 在函数中断言 _size 大于 pos,确保访问 _str 数组元素时不会越界。

  2. 约束函数不能修改对象的成员变量,避免对对象状态造成破坏或影响调用者对对象状态的判断。

错误例子:

 class MyString{public:MyString(const char *str){_str = new char[std::strlen(str) + 1];std::strcpy(_str, str);}​// 错误的 const 成员函数char &operator[](size_t pos) const{return _str[pos]; // 修改了成员变量值}​private:char *_str;};​int main(){const MyString str("Hello");​str[0] = 'h'; // 错误:试图修改常量对象的值​return 0;}

拷贝构造使用const

使用拷贝构造时,最用const进行修饰,以防权限的放大

正确写法:

 Date(const Date &d){_year = d.year;_month = d.month;_year = d.year;}

不用const修饰:

 class Date{public:Date(int year, int month, int day) : _year(year), _month(month), _day(day) {}​// 错误的拷贝构造函数,没有使用 const 修饰符Date(Date &d){_year = d._year + 1;_month = d._month;_day = d._day;}​void PrintDate(){std::cout << "Year: " << _year << ", Month: " << _month << ", Day: " << _day << std::endl;}​private:int _year;int _month;int _day;};​int main(){Date d1(2023, 11, 21);d1.PrintDate(); // 输出:Year: 2023, Month: 11, Day: 21​Date d2 = d1;   // 调用拷贝构造函数d2.PrintDate(); // 输出:Year: 2024, Month: 11, Day: 21​return 0;}

出现的错误:

  1. 逻辑错误:拷贝构造函数中可能会修改成员变量的值,从而导致对象的状态发生改变。如果这不是我们的预期行为,那么就会导致程序逻辑错误。

  2. 破坏不变式:如果被拷贝对象的成员变量有一些不变式,那么拷贝构造函数的修改可能会破坏这些不变式,从而导致程序出错。

    假设有一个 Rectangle 类表示矩形,其中成员变量 widthheight 分别表示矩形的宽度和高度。该类定义了一个不变式,即 widthheight 都必须大于 0。

     class Rectangle {public:Rectangle(int width, int height) : _width(width), _height(height) {}​// 错误的拷贝构造函数,破坏了不变式Rectangle(Rectangle& other) {_width = other._width + 1;  // 修改宽度值_height = other._height;}​private:int _width;int _height;};

    在这个例子中,我们定义了一个错误的拷贝构造函数,其中修改了被拷贝对象的宽度值。这将导致破坏 Rectangle 类的不变式,即宽度必须大于 0。如果我们使用该拷贝构造函数创建一个新的矩形对象,它将具有无效的宽度值,从而导致程序出错

  3. 不可预知的行为:如果被拷贝对象是一个常量对象,那么在拷贝构造函数中修改其成员变量的值是未定义的行为,可能会导致不可预知的结果。

    假设有一个 Person 类表示人员信息,其中成员变量 name 表示人的姓名,而该类对象被声明为常量对象。

     class Person 
    {public:Person(const std::string& name) : _name(name) {}​// 错误的拷贝构造函数,常量对象被修改Person(Person& other) {_name = "Copy of " + other._name;  // 修改姓名}​private:std::string _name;};

    在这个例子中,我们定义了一个错误的拷贝构造函数,其中修改了被拷贝对象的姓名。如果我们使用该拷贝构造函数创建一个常量对象的副本,这将是未定义的行为,可能会导致不可预知的结果。由于常量对象的成员变量应该是不可修改的,所以在拷贝构造函数中修改成员变量将导致不可预知的状态和行为。

相关文章:

【C++】const与类(const修饰函数的三种位置)

目录 const基本介绍 正文 前: 中: 后: 拷贝构造使用const 目录 const基本介绍 正文 前: 中: 后: 拷贝构造使用const const基本介绍 const 是 C 中的修饰符&#xff0c;用于声明常量或表示不可修改的对象、函数或成员函数。 我们已经了解了const基本用法,我们先进行…...

深度学习在图像识别中的革命性应用

深度学习在图像识别中的革命性应用标志着计算机视觉领域的重大进步。以下是深度学习在图像识别方面的一些革命性应用&#xff1a; 1. **卷积神经网络&#xff08;CNN&#xff09;的崭新时代**&#xff1a; - CNN是深度学习在图像识别中的核心技术&#xff0c;通过卷积层、池化…...

R语言读文件“-“变成“.“

R语言读取文件时发生"-"变成"." 如果使用read.table函数&#xff0c;需要 check.namesFALSE data <- read.table("data.tsv", headerTRUE, row.names1, check.namesFALSE)怎样将"."还原为"-" 方法一&#xff1a;gsub函…...

RabbitMQ 基础操作

概念 从计算机术语层面来说&#xff0c;RabbitMQ 模型更像是一种交换机模型。 Queue 队列 Queue&#xff1a;队列&#xff0c;是RabbitMQ 的内部对象&#xff0c;用于存储消息。 RabbitMQ 中消息只能存储在队列中&#xff0c;这一点和Kafka相反。Kafka将消息存储在topic&am…...

自然语言处理:Transformer与GPT

Transformer和GPT&#xff08;Generative Pre-trained Transformer&#xff09;是深度学习和自然语言处理&#xff08;NLP&#xff09;领域的两个重要概念&#xff0c;它们之间存在密切的关系但也有明显的不同。 1 基本概念 1.1 Transformer基本概念 Transformer是一种深度学…...

Ps:裁剪工具 - 裁剪预设的应用

裁剪工具提供了两种类型的裁剪方式。 一种是仅按宽高比&#xff08;比例&#xff09;进行裁剪&#xff0c;常在对图像进行二次构图时采用。 另一种则按指定的图像尺寸&#xff08;宽度值和高度值&#xff09;及分辨率&#xff08;宽 x 高 x 分辨率&#xff09;进行裁剪。其实质…...

前端工程化-什么是构建工具

了解构建工具之前&#xff0c;我们首先要知道的是浏览器只认识html、css、js&#xff0c;而我们开发时用的vue&#xff0c;react框架都只是为了方便我们开发而使用的工具 使用构建工具的原因 vue或react的企业级项目里都会具备这些功能&#xff1a; 1.使用typescript语言&…...

01-论文阅读-Deep learning for anomaly detection in log data: a survey

01-论文阅读-Deep learning for anomaly detection in log data: a survey 文章目录 01-论文阅读-Deep learning for anomaly detection in log data: a survey摘要I 介绍II 背景A 初步定义B 挑战 III 调查方法A 搜索策略B 审查的功能 IV 调查结果A 文献计量学B 深度学习技术C …...

图像处理02 matlab中NSCT的使用

06 matlab中NSCT的使用 最近在学习NSCT相关内容&#xff0c;奈何网上资源太少&#xff0c;简单看了些论文找了一些帖子才懂了一点点&#xff0c;在此分享给大家&#xff0c;希望有所帮助。 一.NSCT流程 首先我们先梳理一下NSCT变换的流程&#xff0c;只有清楚流程才更好的理清…...

提升办公效率,畅享多功能办公笔记软件Notion for Mac

在现代办公环境中&#xff0c;高效的笔记软件对于提高工作效率至关重要。而Notion for Mac作为一款全能的办公笔记软件&#xff0c;将成为你事业成功的得力助手。 Notion for Mac以其多功能和灵活性而脱颖而出。无论你是需要记录会议笔记、管理项目任务、制定流程指南&#xf…...

Apache Airflow (十三) :Airflow分布式集群搭建及使用-原因及

&#x1f3e1; 个人主页&#xff1a;IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;加入大数据技术讨论群聊&#xff0c;获取更多大数据资料。 &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你大数据的个人空间-豹…...

# 聚类系列(一)——什么是聚类?

目前在做聚类方面的科研工作, 看了很多相关的论文, 也做了一些工作, 于是想出个聚类系列记录一下, 主要包括聚类的概念和相关定义、现有常用聚类算法、聚类相似性度量指标、聚类评价指标、 聚类的应用场景以及共享一些聚类的开源代码 下面正式进入该系列的第一个部分&#xff…...

Android DatePicker(日期选择器)、TimePicker(时间选择器)、CalendarView(日历视图)- 简单应用

示意图&#xff1a; layout布局文件&#xff1a;xml <?xml version"1.0" encoding"utf-8"?> <ScrollView xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"…...

linux环境搭建mysql5.7总结

以下安装方式&#xff0c;在阿里云与腾讯云服务器上都测试可用。 一、进入到opt目录下&#xff0c;执行&#xff1a; [rootmaster opt]# wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz解压&#xff1a; [rootmaster opt]#…...

SQL Server Count()函数

SQL Server Count()函数 SQL Server COUNT() 是一个聚合函数&#xff0c;它返回在集合中找到的项目数。 COUNT() 函数语法&#xff1a; COUNT([ALL | DISTINCT ] expression)ALL 指示COUNT() 函数应用于所有值。ALL是默认值。返回非NULL值的数量&#xff08;包括重复值&…...

架构探索之路-第一站-clickhouse | 京东云技术团队

一、前言 架构, 软件开发中最熟悉不过的名词, 遍布在我们的日常开发工作中, 大到项目整体, 小到功能组件, 想要实现高性能、高扩展、高可用的目标都需要优秀架构理念辅助. 所以本人尝试编写架构系列文章, 去剖析市面上那些经典优秀的开源项目, 学习优秀的架构理念来积累架构设…...

易航网址引导系统 v1.9 源码:去除弹窗功能的易航网址引导页管理系统

易航自主开发了一款极其优雅的易航网址引导页管理系统&#xff0c;后台采用全新的光年 v5 模板开发。该系统完全开源&#xff0c;摒弃了后门风险&#xff0c;可以管理无数个引导页主题。数据管理采用易航原创的JsonDb数据包&#xff0c;无需复杂的安装解压过程即可使用。目前系…...

创新无界:通义灵码在测试过程中展现的独特魅力

通义灵码基于通义大模型&#xff0c;提供代码智能生成、研发智能问答能力。本文就来介绍下通义灵码在测试过程中的应用。 操作手册&#xff1a; 通义灵码, 阿里云提供的一款基于通义大模型的智能编码辅助工具_云效-阿里云帮助中心 1. 什么是通义灵码 是阿里云出品的一款基于通…...

crmchat安装搭建教程文档 bug问题调试

一、安装PHP插件&#xff1a;fileinfo、redis、swoole4。 二、删除PHP对应版本中的 proc_open禁用函数。 一、设置网站运行目录public&#xff0c; 二、设置PHP版本选择纯静态。 三、可选项如有需求则开启SSL,配置SSL证书&#xff0c;开启强制https域名。 四、添加反向代理。 …...

Golang http 请求如何设置代理

ENV golang 1.17 使用代理 需要在创建 http client 的时候设置&#xff0c;使 http 库能够捕获环境变量 示例 func newClient(cert tls.Certificate) (*http.Client, error) {config : &tls.Config{Certificates: []tls.Certificate{cert},}config.BuildNameToCertific…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...