C++从入门到精通——const与取地址重载
const与取地址重载
- 前言
- 一、const
- 正常用法
- const成员函数
- 问题
- `const`对象可以调用非`const`成员函数吗
- 非`const`对象可以调用`const`成员函数吗
- `const`成员函数内可以调用其它的非`const`成员函数吗
- 非`const`成员函数内可以调用其它的`const`成员函数吗
- 总结
- 二、取地址及const取地址操作符重载
- 概念
- 示例
前言
类的6个默认成员函数:如果一个类中什么成员都没有,简称为空类。
空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
class Date {};

一、const
正常用法
在C++中,可以使用const关键字来声明一个常量成员。常量成员是指在类中声明的成员变量被标记为只读,即不能在类的方法中进行修改。常量成员的值在对象创建时被初始化,并且在对象的整个生命周期中保持不变。
常量成员的声明方式为在成员变量的类型前加上const关键字。例如:
class MyClass {
public:const int myConst = 10; // 常量成员的声明和初始化
};
在上述示例中,myConst被声明为一个常量成员,其初始值为10。
const成员函数
除了上面的这种用法外,C++在类里定义了新的const用法,将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

我们来看看下面的代码
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << "Print()" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}void Print() const{cout << "Print()const" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}
private:int _year; // 年int _month; // 月int _day; // 日
};
void Test()
{Date d1(2022, 1, 13);d1.Print();const Date d2(2022, 1, 13);d2.Print();
}
问题
请思考下面的几个问题:
const对象可以调用非const成员函数吗
不可以。在C++中,一个对象如果被声明为const,则表示该对象是只读的,其成员变量不能被修改。因此,一个const对象只能调用其成员函数中被声明为const的成员函数。
如果一个成员函数没有被声明为const,则它默认是一个非const成员函数。非const成员函数可以修改对象的成员变量,因此不能被const对象调用。
如果一个成员函数需要被const对象调用,应该在函数声明的末尾加上const关键字。这样声明的成员函数被称为const成员函数,它保证不修改对象状态,并且可以被const对象调用。
示例:
class MyClass {
public:void nonConstFunc() {// 可以修改对象状态的非const成员函数}void constFunc() const {// 不能修改对象状态的const成员函数}
};int main() {const MyClass obj;obj.constFunc(); // 可以调用const成员函数// obj.nonConstFunc(); // 错误,不能调用非const成员函数return 0;
}
在上述示例中,constFunc()被声明为const成员函数,因此可以被const对象调用。而nonConstFunc()是非const成员函数,因此不能被const对象调用。
非const对象可以调用const成员函数吗
正确,非const对象可以调用const成员函数。const成员函数的作用是表示该函数不会修改对象的状态。因此,无论是const对象还是非const对象,都可以调用不会修改对象状态的const成员函数。
示例:
class MyClass {
public:void nonConstFunc() {// 可以修改对象状态的非const成员函数}void constFunc() const {// 不能修改对象状态的const成员函数}
};int main() {MyClass obj;obj.constFunc(); // 可以调用const成员函数obj.nonConstFunc(); // 也可以调用非const成员函数return 0;
}
在上述示例中,constFunc()是const成员函数,因此可以被非const对象obj调用。同时,非const成员函数nonConstFunc()也可以被非const对象obj调用。因为非const对象可以修改对象的状态,所以可以调用const成员函数和非const成员函数。
const成员函数内可以调用其它的非const成员函数吗
在const成员函数内部,只能调用其他const成员函数。const成员函数的作用是保证不修改对象的状态,因此它们不能调用非const成员函数。如果在const成员函数内部调用非const成员函数,编译器将会报错。
示例:
class MyClass {
public:void nonConstFunc() {// 可以修改对象状态的非const成员函数}void constFunc() const {// 不能修改对象状态的const成员函数nonConstFunc(); // 错误! const成员函数不能调用非const成员函数}
};int main() {MyClass obj;obj.constFunc();return 0;
}
在上述示例中,constFunc()是const成员函数,它尝试在内部调用了非const成员函数nonConstFunc(),这将导致编译错误。
如果确实需要在const成员函数内部调用非const成员函数,可以使用const_cast进行类型转换,但是这样会绕过const的限制,不推荐使用。
void constFunc() const {const_cast<MyClass*>(this)->nonConstFunc(); // 可以调用非const成员函数,但不推荐使用
}
非const成员函数内可以调用其它的const成员函数吗
非const成员函数可以调用其他的const成员函数。在非const成员函数内部,可以调用任何类型的成员函数,包括const成员函数。这是因为非const成员函数可以修改对象的状态,而const成员函数不允许修改对象的状态,所以在非const成员函数内部调用const成员函数是安全的。
示例:
class MyClass {
public:void nonConstFunc() {// 可以修改对象状态的非const成员函数constFunc(); // 可以调用const成员函数}void constFunc() const {// 不能修改对象状态的const成员函数}
};int main() {MyClass obj;obj.nonConstFunc(); // 调用非const成员函数,它内部调用了const成员函数return 0;
}
在上述示例中,nonConstFunc()是非const成员函数,它内部调用了const成员函数constFunc(),这是允许的。因为非const成员函数可以修改对象的状态,包括调用const成员函数不会破坏对象的const属性。
总结
权限缩小可以,权限放大不可以,即被const修饰的是可读的,不被修饰的是可读可写的,不被修饰的可以访问被修饰的
二、取地址及const取地址操作符重载
概念
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。 不想知道太多的读者可以直接跳过。
class Date
{
public:Date* operator&(){return this;}const Date* operator&()const{return this;}
private:int _year; // 年int _month; // 月int _day; // 日
};
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!
示例
在C++中,const关键字用于修饰变量,表示该变量的值不可修改。const修饰符同样也可以用于指针,表示指针所指向的内容是不可修改的。
在C++中,对于指针类型,可以重载取地址操作符(&)来返回指针的地址。但是,const修饰符的存在可能导致取地址操作符无法重载。
当一个指针被声明为const类型时,取地址操作符不会返回指针的地址,而是返回指针指向的内容的地址。这是因为const关键字修饰的指针表示其所指向的内容是不可修改的,因此不需要返回指针的地址。
以下是一个示例代码,展示了如何重载取地址操作符和处理const修饰符:
#include <iostream>class MyClass {
private:int value;public:MyClass(int value) : value(value) {}int* operator&() {std::cout << "Non-const operator&" << std::endl;return &value;}const int* operator&() const {std::cout << "Const operator&" << std::endl;return &value;}
};int main() {MyClass obj(10);int* ptr1 = &obj; // 调用非const版本的operator&const int* ptr2 = &obj; // 调用const版本的operator&return 0;
}
输出结果为:
Non-const operator&
Const operator&
在上述代码中,类MyClass重载了取地址操作符(&)。它包含两个版本:一个是非const版本,另一个是const版本。
在main()函数中,先后使用非const指针和const指针获取MyClass对象的地址。当使用非const指针时,调用非const版本的operator&;而当使用const指针时,调用const版本的operator&。
通过重载取地址操作符,我们可以根据指针的类型选择合适的操作。对于const修饰符,我们还可以使用const版本的operator&来获取指向内容的地址。
相关文章:
C++从入门到精通——const与取地址重载
const与取地址重载 前言一、const正常用法const成员函数问题const对象可以调用非const成员函数吗非const对象可以调用const成员函数吗const成员函数内可以调用其它的非const成员函数吗非const成员函数内可以调用其它的const成员函数吗总结 二、取地址及const取地址操作符重载概…...
手写spring IOC底层源码来模拟spring如何利用多级缓存解决循环依赖的问题
在文章开始之前,先来看一张spring IOC加载过程的脑图吧 Spring IOC的加载过程 首先,当我们去new了一个applicationContext,它底层呢就会把我们配置的bean进行扫描,然后创建成一个一个的beanDefinition放在我们的beanDefinitionMap中,此时就有了一切创造bean的原料信…...
C++11 Thead线程和线程池
参考资料: 2、5.lock_guard 与 std::unique_lock-陈子青的编程学习课堂 (seestudy.cn) 3、C11 多线程编程-小白零基础到手撕线程池_哔哩哔哩_bilibili 一、 C11 Thead线程库的基本使用 # include <thread> std::thread t(function_name, args...); // 线…...
Windows版Apache 2.4.59解压直用(免安装-绿色-项目打包直接使用)
windows下Apache分类 Apache分为 安装版和解压版 安装版: 安装方便,下一步------下一步就OK了,但重装系统更换环境又要重新来一遍,会特别麻烦 解压版(推荐): 这种方式(项目打包特别方便&#x…...
刀具表面上的微结构
刀具表面微结构通常指在刀具表面对特定功能设计的微观纹理,这些纹理可以是沟槽、凹坑、凸起或任何其他形式的微观图案。这些微结构的设计和应用是为了改善刀具的切削性能,减少切削力和切削温度,提高切削效率和精度,同时降低切削液…...
css3实现微信扫码登陆动画
在做微信扫码登陆时,出现一个背景光图上下扫码动画,用css3图片实现。 实现原理: 1.准备一个渐变的背景.png图 2.css动画帧实现动画 看效果: css代码: #wx-scan{position: absolute;top:0px;left: 50%;z-index: 3;ma…...
vue3 导入excel数据
所需包 "xlsx": "^0.18.5"页面导入包 import * as XLSX from xlsx; import {genFileId, UploadProps, UploadRawFile,ElTable } from element-plus;页面 <el-upload accept".xlsx" :on-change"changeExcel" :on-exceed"ha…...
C# linq 根据多字段动态Group by
实现类: public static class LinqHepler {/// <summary>/// 根据单个字段动态Group/// </summary>/// <typeparam name"T"></typeparam>/// <param name"source"></param>/// <param name"prop…...
C语言学习/复习22----阶段测评编程题
一、阶段测评练习 题1: 题2:...
LeetCode-1766. 互质树【树 深度优先搜索 广度优先搜索 数组 数学 数论】
LeetCode-1766. 互质树【树 深度优先搜索 广度优先搜索 数组 数学 数论】 题目描述:解题思路一:DFS 中记录节点值的深度和编号,回溯写法。关键点是1 < nums[i] < 50解题思路二:0解题思路三:0 题目描述࿱…...
“数据安全服务能力”评定资格认证!不容错过
数据安全服务能力评定是指对数据安全服务提供商从事数据安全服务综合能力的评定,包括技术能力、服务能力、质量保证能力、人员构成与素质、经营业绩、资产状况等要素。 一、能力评定类型与等级 数据安全服务能力分为二个类型:数据安全评估、数据安全建…...
【MATLAB 分类算法教程】_3麻雀搜索算法优化支持向量机SVM分类 - 教程和对应MATLAB代码
分类代码案例3:麻雀搜索算法优化支持向量机SVM分类 - MATLAB完全代码教程 1. 初始化代码2.读取数据代码3.数据预处理代码4.利用麻雀搜索算法SSA求解最佳的SVM参数c和g代码5.根据最佳的参数进行SVM模型训练代码6.SVM模型预测代码7.准确率分析以及分类结果对比作图代码本文以红酒…...
利用机器学习库做动态定价策略的例子
动态定价是一个复杂的问题,涉及到市场需求、库存、竞争对手行为、季节性因素等多个变量。在实际应用中,动态定价通常需要复杂的模型和大量的数据分析。我选择使用Python(Golearn库)进行机器学习模型的训练和部署,而将G…...
Tcpdump -r 解析pcap文件
当我们使用命令抓包后,想在命令行直接读取筛选怎么办?-r参数就支持了这个 当你使用 tcpdump 的 -r 选项读取一个之前捕获的数据包文件,并想要筛选指定 IP 地址和端口的包时,你可以在命令中直接加入过滤表达式。这些过滤表达式可以…...
[dvwa] sql injection(Blind)
blind 0x01 low 1’ and length(version()) 6 # syntax: substr(string , from<start from 1>, cut length) 1’ and substr(version(),1,1) ‘5’ # 1’ and substr(version(),2,1) ‘.’ # 1’ and substr(version(),3,1) ‘7’ # 1’ and substr(version(),4,…...
linux 挂载云盘 NT只能挂载2T,使用parted挂载超过2T云盘
一、删除原来挂载好的云盘和分区 1、查看挂载号的云盘 fdisk -l 发现我们有5千多G但是只挂载了2T,心里非常的慌张!十分的不爽! 好,我们把它干掉,重新分区! 2、解除挂载 umount /homeE 没保存跳转到&…...
用Skimage学习数字图像处理(021):图像特征提取之线检测(下)
本节是特征提取之线检测的下篇,讨论基于Hough变换的线检测方法。首先简要介绍Hough变换的基本原理,然后重点介绍Skimage中含有的基于Hough变换的直线和圆形检测到实现。 目录 10.4 Hough变换 10.4.1 原理 10.4.2 实现 10.4 Hough变换 Hough变换&…...
ArduPilot飞控之Gazebo + SITL + MP的Jetson Orin环境搭建
ArduPilot飞控之Gazebo SITL MP的Jetson Orin环境搭建 1. 源由2. Linux环境整理3. 安装Gazebo环境3.1 安装Gazebo3.2 安装插件3.3 配置插件3.4 测试Gazebo 4. 安装Arudpilot-SITL环境4.1 克隆工程4.2 编译准备4.3 环境配置4.4 配置编译4.5 测试运行 5. 测试运行6. 参考资料 1…...
前端错误监控的方法有哪些
前端错误监控是指通过各种手段收集、分析和处理前端应用运行中发生的错误 常用的前端错误监控的方法有 使用 try catch 方法 捕获特定代码块中的错误多用于处理特定函数或代码段可能抛出的异常,尤其是异步代码网络请求错误监控 promise.catchtry catch全局错误处理…...
✌粤嵌—2024/3/11—跳跃游戏
代码实现: 方法一:递归记忆化 int path; int used[10000];bool dfs(int *nums, int numsSize) {if (path numsSize - 1) {return true;}for (int i 1; i < nums[path]; i) {if (used[path i]) {continue;}path i;used[path] 1;if (dfs(nums, num…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
