C++:常量
const的最初动机
const的使用方法
使用const的好处是允许指定一种语义上的约束,即某种对象不能被修改,且由编译器具体实施这种约束。
const声明格式:const 类型名 对象名;
修饰普通变量,时期不能被随意修改
【注意】1.C++中的const为内部连接,即由const定义的常量仅在被定义的文件中才能看见,除非使用extern。一般情况下,编译器不为const分配空间(而extern则强制分配空间)。
2. 当定义一个常量(const)时,必须进行初始化,即赋初值给它,除非已经用extern最清楚说明。
可以使用const修饰数组,表示“常”数组,即数组的值不能被修改。例如
const int data[] = { 1, 2, 3 };//合法使用,定义一个常量数组
struct MyStruct
{int i, j;
};
const MyStruct mList[] = { {1, 2}, {3, 4} };//定义一个结构体常量数组
data[0] = 10; //错误
mList[1].i = 4;//错误
同时,定义上述数组后,对常数组的一下引用也是错误的。
char cList[data[2]];//错误
float fList[mList[0].i];//错误
错误原因在于,在编译时编译器必须为数组分配固定大小的内存。而用const修饰的数组意味着“不能被改变”的一块存储区,但其值在编译期间不能被使用。
const与指针
const与指针的结合使用由两种情况:1.用const修饰指针,即修饰存储在指针里的地址;2.修饰指针指向的对象。
为了防止使用混乱,采用“就近原则”,即const距离哪个近就修饰哪个:若const距离变量近,则表示的含义为指向常量的指针;若const距离指针近,则表达的含义为指向变量的常指针。
指向常量的指针
定义格式:const 类型名* 指针变量名;
或者类型名 const* 指针变量名;
这两种格式是等价的。
const int data = 10;
const int *p = &a;
*p = 20; //错误
const int max = 20;
p = &max; //正确
表明p是一个指向const int的指针。指针所指向的单元不能修改,但是其本身为指针变量可以指向别的位置。
常指针
定义格式为:类型名 *const 指针名;
int i = 1;
int * const p = &i;
表明p是一个常指针,一个指向int类型的变量i的const指针,p必须用一个初值,它只能指向这个初始对象i,不能“被改变”而指向其他对象,但对象的值可以被修改。
同时,不仅可以使用一个常指针指向一个变量,也可以把非const对象变成const对象。例如:
int a = 10;
int *const p = &a; //可以用const指针指向一个非const对象
const int *const q = &a;//可以把const对象地址赋值给const对象指针
const与函数
函数与const的结合使用由两种方式:1.参数为const类型;2.返回值为const类型。
const类型的参数
定义格式:返回值类型 函数名称(const 类型 参数名,···)
例如:
void f(const int i){i++;//错误
}
当c++在函数的参数使用引用时,需要特别注意对常量引用的使用。例如:
void f1(int&) {}
void f2(const int&) {}
int main() {f1(1);//错误,在f1()中,可以修改参数内容,而1为常量f2(1);//正确,在f2()中,参数声明为常量int n = 10;const int m = 11;f1(n);//正确f1(m);//错误,不能使用普通引用方式引用常量f2(n);//正确,可以用常量方式引用普通常量f2(m);//正确return 0;
}
const类型的返回值
可以用const修饰函数的返回值,即函数返回一个常量值,此常量值即可以赋给常量(对常量初始化),也可以赋给变量。其对返回值为某个类对象时,会显得尤为重要。
常对象的使用:
class MyClass
{
public:MyClass(int i = 0):data(i){}void seti(int i) {data = i;}
private:int data;
};
MyClass test1() {return MyClass();//返回为普通对象
}
const MyClass test2() {return MyClass();//返回为常对象
}
int main() {test1() = MyClass(10);//正确,test1()返回一个MyClass对象,并把对象MyClass(10)的值赋给它test1().seti(20);//正确,调用test1(),得到一个返回对象,并调用此对象的成员函数seti()test2() = MyClass(10);//错误,常对象不能被修改(赋值)test2().seti(20);//错误,常对象不能被修改return 0;
}
const与类
const在类里有两种应用:1.是在类里建立类内局部常量,可用在常量表达式中,而常量表达式在编译期间被求职;2.是const和类成员函数的结合使用。
类内const局部常量
在一个类内使用const修饰的意思就是“在这个对象的寿命期内,这是一个常量。”然而,对这个常量来讲,每个不同的对象可以含有一个不同的值。
在类内建立一个const成员时不能赋初值,只能在构造函数里面对其赋初值,而且要放在构造函数的特殊地方,因为const必须在创建它的地方被初始化,所以在构造函数的主体里,const成员必须已被初始化。例如:
class MyClass
{
public:MyClass():num(100){}
private:const int num;
};
常用的一种情况就是,在类内声明一个常量,用这个常量来定义数组的大小,把数组的大小隐藏在类内。
错误示范:
class MyClass
{
public:MyClass();
private:const int num = 100;//错误int data[100];//错误
};
因为在类内进行存储空间分配时,编译器无法知道const的内容是什么,所以不能把它用于编译期间的常量。
解决这种问题的方法有两种:
- 静态常量。为提高效率保证所有的类对象最多只有一份拷贝值,通常需要将常量声明为是静态的。例如:
class MyClass{static const int num = 100;int mList[num];
};
- enum(枚举常量)。例如:
class MyClass{enum{num = 100};int data[num];
};
常对象与常成员函数
声明一个“复杂”的对象为常量,对于公有数据这点很容易做到,然而对于私有数据,该如何保证每个成员函数的调用不改变呢?需要声明这个成员函数为const类型,等同于告诉编译器此类的一个const对象可以调用这个成员函数,而const对象调用非const成员函数。
const成员函数定义格式:class 类名{返回值类型 成员函数名称(参数列表) const;};
【注意】若在函数的前面加上const,则表明函数返回值为const,为防止混乱,应把const放在函数的后面。在一个const成员函数里,试图改变任何数据成员或调用非const成员函数,编译器都将显示出错误信息。
例如:const成员函数与非const成员函数使用方式的比较。
//student.h
#ifndef STUDENT_H_//防止重复包含头文件student.h
#define STUDENT_H_
class Student{int No;char Name[20];
public:Student();int GetNo() const;//const成员函数const char* GetName();//返回值为const的成员函数,不是const成员函数
};
#endif
//student.cpp
#include <string.h>
#include <student.h>
Student::Student(){No = 1;strcpy(Name, "wang");
}
int Student::GetNo()const{return No;
}
const char* Student::GetName(){return Name;
}
//test.cpp
#include <student.h>
int main(){Student s1;s1.GetNo();s1.GetName();const Student s2;s2.GetNo();//正确,常对象调用const成员函数s2.GetName();//错误,常对象调用了非const成员函数return 0;
然而,有时候我们需要修改对象的某些数据成员时该怎么办?有两种方法.
1.强制转换。在常成员函数中修改成员变量的值。
class Test{int i, j;
public:Test():i(0),j(0){};void f()const;
};
void Test f()const{i = 1; //错误,在常成员函数中修改类成员((Test*)this)->j = 5; //正确
}
int main(){const Test t;t.f();//正确return 0;
}
- 使用mutable,用它指定某个特定的数据成员在常量对象的某个函数里是可以被修改的。在常成员函数中修改有mutable所修改的变量值。
class Test{int i;mutable int j;
public:Test():i(0),j(0){};void f()const;
};
void Test f()const{i = 1; //错误,在常成员函数中修改类成员j = 5; //正确,可以在常成员函数中修改被mutable修饰的类成员
}
int main(){const Test t;t.f();//正确return 0;
}
相关文章:
C++:常量
const的最初动机 const的使用方法 使用const的好处是允许指定一种语义上的约束,即某种对象不能被修改,且由编译器具体实施这种约束。 const声明格式:const 类型名 对象名;修饰普通变量,时期不能被随意修改 【注意】1.C中的const…...

java JDBC 连接数据库
必须先插入工具包 DataSource ds JdbcHelper.getDs();System.out.println(ds);JdbcTemplate jdbcTemplatenew JdbcTemplate(ds);System.out.println(jdbcTemplate);//新增String sql1"insert into biao values(null,?,?,?)";int ijdbcTemplate.update(sql1,"…...

图神经网络|5.消息传递的计算方法 6.多层GNN的作用
5.消息传递的计算方法 边的存放方式 注意,在实际的边的实现方式中,并不是以邻接矩阵来进行实现的,这是因为在图的更新中,用邻接矩阵进行更新所占用的时间开销相对大,二是因为领接矩阵占用的空间大(N方&am…...

构建中国人自己的私人GPT
创作不易,请大家多鼓励支持。 在现实生活中,很多人的资料是不愿意公布在互联网上的,但是我们又要使用人工智能的能力帮我们处理文件、做决策、执行命令那怎么办呢?于是我们构建自己或公司的私人GPT变得非常重要。 先看效果 一、…...

添加气泡与菜单
目录 1、添加气泡 1.1、文本提示气泡 1.2、带按钮的提示气泡 1.3、自定义气泡 2、菜单 2.1、创建默认样式的菜单 2.2、创建自定义样式的菜单 1、添加气泡 Popup属性可绑定在组件上显示气泡弹窗提示,设置弹窗内容、交互逻辑和显示状态。主要用于…...

python代码练习:双指针法
题目一:移除元素 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不…...
C++系列十七:访问控制符
访问权限控制符 一、public访问权限二、private访问权限三、protected访问权限 在C中,访问权限控制符用于限制类成员的访问权限,主要包括public、private和protected三种。这些访问权限控制符用于控制类成员的访问级别,从而保证数据的封装性和…...
postgresql 最简主从配置
实验目的 配置一个最简的主从环境,了解基本的主从配置。 环境参数 操作系统CentOS Linux release 7.9.2009 (Core)数据库版本PostgreSQL 10.23主库端口15431备库端口15432 因为只是做实验,所以主备库放在同一台机器上,仅通过端口区分主备…...

ubuntu 安装 anaconda
ubuntu 安装 anaconda 下载 wget https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh安装 bash Anaconda3-2023.09-0-Linux-x86_64.sh2.1 回车继续 2.2 许可协议 输入 q 退出阅读许可协议 2.3 输入 yes 接受 许可协议 2.4 设置 anaconda 安装位置 如不需…...
DOM 被劫持
文档对象模型(DOM)充当着 HTML 和 JavaScript 之间的接口,搭建起静态内容与动态交互之间的桥梁,对现代 Web 开发而言,DOM 的作用不可或缺。 然而,DOM 也有一个致命的陷阱 —— DOM 劫持。DOM 劫持是指当 H…...

PIG框架学习2——资源服务器的配置详解
一、前言 1、pig资源服务器的配置 Spring Security oauth2相关的依赖是在pigx-common-security模块中引入的,其他模块需要进行token鉴权的,需要在微服务中引入pigx-common-security模块的依赖,从而间接引入相关的Spring security oauth2依赖…...
vue+element ui实现图片上传并拖拽进行图片排序
用到的技术栈: vue2element Uivue-dragging 如何使用: 第一步: 安装 npm install awe-dnd --save第二步: 引入 main.js 文件 // 引入组件 import VueDND from awe-dnd // 添加至全局 Vue.use(VueDND)具体项目代码 <el-form-item label"封面…...

国产服务器 BIOS下组建RADI不同RAID卡-超详细
国产服务器 长城 组建Raid的方法 说明 大多数国产服务器通用型服务器进入BIOS的都是按DEL键。 9361RAID卡组建方法 在服务器启动过程中,按下DEL键进入BIOS界面。 进入设备管理器,选择AVAGO MegaRAID页签。 3. 进入RAID卡设备,选择Main Me…...

UE4 4.21-4.27使用编辑器蓝图EditorBlueprint方法
在UE4 4.21中,编辑器蓝图(Editor Blueprint)是一个强大的工具,允许开发者扩展和自定义Unreal编辑器的功能。通过编辑器蓝图,我们可以创建自定义的工具和功能,以优化开发流程。 本教程将指导您如何在UE4 4.…...

105、Zero-1-to-3: Zero-shot One Image to 3D Object
简介 官网 使用合成数据集来学习相对摄像机视点的控制,这允许在指定的摄像机变换下生成相同对象的新图像,用于从单个图像进行三维重建的任务。 实现流程 输入图像 x ∈ R H W 3 x \in \R^{H \times W \times 3} x∈RHW3,所需视点的相…...

scala 安装和创建项目
Scala,一种可随您扩展的编程语言:从小型脚本到大型多平台应用程序。Scala不是Java的扩展,但它完全可以与Java互操作。在编译时,Scala文件将转换为Java字节码并在JVM(Java虚拟机)上运行。Scala被设计成面向对…...

Python办公自动化 – 自动化文本翻译和Oracle数据库操作
Python办公自动化 – 自动化文本翻译和Oracle数据库操作 以下是往期的文章目录,需要可以查看哦。 Python办公自动化 – Excel和Word的操作运用 Python办公自动化 – Python发送电子邮件和Outlook的集成 Python办公自动化 – 对PDF文档和PPT文档的处理 Python办公自…...

如何在Win10电脑接收苹果手机日程提醒呢?
有很多小伙伴手机使用的是iPhone苹果手机,但办公电脑使用的win10系统的电脑,这时候如果想要在win10电脑上同步接收苹果手机上设置的日程提醒,该怎么操作呢?如何在win10电脑接收苹果手机日程提醒呢? 如果你设置的日程提…...
227.【2023年华为OD机试真题(C卷)】小明找位置(二分查找-JavaPythonC++JS实现)
🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-小明找位置二.解题思路三.题解代码Python题解代…...

【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》
【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》 写在最前面私钥加密与伪随机性 第二部分流加密与CPA多重加密 CPA安全加密方案CPA安全实验、预言机访问(oracle access) 操作模式伪随机函数PR…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...
ThreadLocal 源码
ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...

渗透实战PortSwigger Labs指南:自定义标签XSS和SVG XSS利用
阻止除自定义标签之外的所有标签 先输入一些标签测试,说是全部标签都被禁了 除了自定义的 自定义<my-tag onmouseoveralert(xss)> <my-tag idx onfocusalert(document.cookie) tabindex1> onfocus 当元素获得焦点时(如通过点击或键盘导航&…...