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&来获取指向内容的地址。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/823468.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何用Jenkins执行自动化测试构建

摘要 依据Jenkins官网介绍&#xff0c;Jenkins是一个流行的开源持续集成和交付工具&#xff0c;它提供了一个可扩展的插件生态系统&#xff0c;可以用于自动化构建、测试和部署软件项目。 本文介绍如何安装使用Jenkins、常见问题解决方案以及深入应用&#xff0c;为自动化测试…

艾迪比皮具携手工博科技SAP ERP公有云,打造数字化转型新标杆

4月1日&#xff0c;广州市艾迪比皮具有限公司&#xff08;以下简称“艾迪比”&#xff09;SAP S/4HANA Cloud Public Edition&#xff08;以下简称“SAP ERP公有云”&#xff09;项目正式启动。双方项目组领导、成员出席本次项目启动会&#xff0c;为未来项目的顺利实施打下坚实…

滚雪球学Java(74):深入理解JavaSE输入输出流:掌握数据流动的奥秘

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴 bug菌&#xff0c;今天又来给大家手把手教学Java SE系列知识点啦&#xff0c;赶紧出来哇&#xff0c;别躲起来啊&#xff0c;听我讲干货记得点点赞&#xff0c;赞多了我就更有动力讲得更欢哦&#xff01;所以呀&…

nginx学习记录-动静分离

1. 动静分离原理 我们在访问网站资源的时候&#xff0c;通常会将资源分成两种&#xff0c;一种是静态资源&#xff08;前端的固定界面&#xff0c;比如图片&#xff0c;html页面等&#xff09;&#xff0c;这些资源无需后台程序处理&#xff1b;另一种是动态资源&#xff0c;这…

分布式调度器

xxl-job介绍 xxl-job 是一个轻量级分布式任务调度框架&#xff0c;支持动态添加、修改、删除定时任务&#xff0c;支持海量任务分片执行&#xff0c;支持任务执行日志在线查看和分页查询&#xff0c;同时支持任务失败告警和重试机制&#xff0c;支持分布式部署和高可用。xxl-j…

阿里云、腾讯云、华为云优惠券领取入口整理汇总

阿里云、腾讯云、华为云作为国内领先的云服务提供商&#xff0c;一直以其稳定、高效、安全的服务赢得了广大用户的青睐。为了回馈用户&#xff0c;这些云平台经常会推出各种优惠活动&#xff0c;其中最为常见的便是优惠券。本文将为大家整理汇总阿里云、腾讯云、华为云优惠券的…

linux-centos虚拟机设置固定ip

环境准备 虚拟机版本&#xff1a;centos7 安装环境&#xff1a;vmware17 1、设置网络连接 虚拟机-设置-网络适配器-NAT模式 2、查看子网信息 编辑-虚拟网络编辑器-NAT模式-NAT设置 查看子网ip和网关ip 下一步要用 3、修改配置文件 vim /etc/sysconfig/network-scripts…

构建数据平台架构指导原则与平台核心组件说明

文章目录 前言什么是数据架构&#xff1f;数据架构如何帮助构建数据平台&#xff1f;数据平台核心组件数据源系统数据加载数据存储数据处理和转换提供使用数据的方式公共服务 前言 湖仓一体是最近几年非常流行的现代大数据架构&#xff0c;目前它已经成为设计数据平台架构的首…

Flask框架初探-如何在本机发布一个web服务并通过requests访问自己发布的服务-简易入门版

Flask框架初探 在接触到网络框架之前我其实一直对一个事情有疑惑&#xff0c;跨语言的API在需要传参的情况下究竟应该如何调用&#xff0c;之前做过的项目里&#xff0c;我用python做了一个代码使用一个算法得到一个结果之后我应该怎么给到做前端的同学或者同事&#xff0c;之前…

基于springboot 的医院信管系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

SpringBoot新增菜品模块开发(事务管理+批量插入+主键回填)

需求分析与设计 一&#xff1a;产品原型 后台系统中可以管理菜品信息&#xff0c;通过 新增功能来添加一个新的菜品&#xff0c;在添加菜品时需要选择当前菜品所属的菜品分类&#xff0c;并且需要上传菜品图片。 新增菜品原型&#xff1a; 当填写完表单信息, 点击"保存…

【数据分析】AHP层次分析法

博主总结&#xff1a;根据每个方案x各准则因素权重累加结果 对比来选择目标。数据主观性强 简介 AHP层次分析法是一种解决多目标复杂问题的定性和定量相结合进行计算决策权重的研究方法。该方法将定量分析与定性分析结合起来&#xff0c;用决策者的经验判断各衡量目标之间能…

【数字人】AIGC技术引领数字人革命:从制作到应用到全景解析

AIGC技术引领虚拟数字人革命&#xff1a;从制作到应用的全景解析 一、AIGC技术为虚拟数字人注入智能灵魂二、AIGC型虚拟人制作流程实例分析1、采集数据2、建模3、内容生成 三、AIGC在虚拟数字人应用中的案例分析四、总结与展望 在科技的浪潮中&#xff0c;AIGC&#xff08;人工…

Ubuntu:VSCode中编译运行C++代码

版本&#xff1a;Ubuntu22.04.1 LTS 目录 1 安装VSCode并汉化 2 检查Ubuntu是否已经安装了 GCC 3 在VScode中安装C/C扩展 4 在VSCode中进行C/C配置 1 安装VSCode并汉化 安装VSCode&#xff08;参考之前博客Ubuntu&#xff1a;安装VSCode_ubuntu vscode-CSDN博客&#xff…

Linux sort/uniq/wc

文章目录 1. sort 排序将线程ID从大到小排序 2.uniq 临近去重3.wc word cnt 统计 1. sort 排序 将线程ID从大到小排序 grep -v是反向筛选&#xff0c;利用USER&#xff0c;排除掉首行 awk是打印第1 2列 sort -n是代码以数值大小做排序&#xff0c;不加的话会以字符排序。 -k是…

Gitee和Git学习笔记

Gitee和Git指令 Gitee提交代码方法1 先将仓库clone到本地&#xff0c;修改后再push到 Gitee 的仓库方法2 本地初始化一个仓库&#xff0c;设置远程仓库地址后再做push 切换分支下载代码通过git clone克隆仓库通过下载 ZIP 的方式下载代码 Git提交指令 解决本地库同时关联GitHub…

(C语言入门)复合类型、内存管理

目录 复合类型&#xff08;自定义类型&#xff09; 概述&#xff1a; 结构体变量的定义和初始化&#xff1a; 结构体成员的使用&#xff1a; 结构体做函数参数&#xff1a; 结构体值传参&#xff1a; 结构体地址传参&#xff1a; 共用体&#xff08;联合体&#xff09;&…

测试人员如何做好工作量评估和风险把控?

今天想聊一聊关于测试工作量评估及需求进度把控的内容。 我个人觉得有时候评估测试工作量其实也挺难的&#xff0c;比如有的需求没有需求文档&#xff0c;只能靠自己对需求的理解去大概评估&#xff0c;有可能评估的工作量比实际需要的工作量会少点&#xff0c;对于每周进行迭…

【Index to Lectures or Courses】

文章目录 1 Speech / Course2 Material3 Basic knowledge and tools4 职位缩写你知道几个? 1 Speech / Course 《中国文化文概论》&#xff08;武汉大学&#xff09;【Paper material】【阅读笔记】【Reading Notes】&#xff08;1&#xff09;【Reading Notes】&#xff08;…

Mybatis-plus中的分页操作

Mybatis-plus中的分页操作 1.导入Mybatis-plus依赖2.创建mybatis配置类3.参数 1.导入Mybatis-plus依赖 因为是一个springboot项目&#xff0c;其中的pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns&q…