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.rhkb.cn/news/312623.html

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

相关文章

ubuntu 更改 ssh 默认端口 22 以加固安全

出于加固安全考虑&#xff0c;一般公司会禁用 ssh 的 22 端口号&#xff0c;因此我们需要改为其他端口。 1、ssh 命令行登录 进入台式机&#xff0c;修改 /etc/ssh/sshd_config 文件中的 Port 配置行&#xff0c;将 22 改为 8022&#xff0c;保存修改后&#xff0c;重启 ssh 服…

c++的学习之路:24、 二叉搜索树概念

摘要 本章主要是讲一下二叉搜索树的实现 目录 摘要 一、二叉搜索树概念 二、 二叉搜索树操作 1、二叉搜索树的查找 2、二叉搜索树的插入 3、二叉搜索树的删除 三、二叉搜索树的实现 1、插入 2、中序遍历 3、删除 4、查找 四、二叉搜索树的递归实现 1、插入 2、删…

LLM推理框架Triton Inference Server学习笔记(二): Triton模型部署流程(stey by stey)

官方文档查阅: TritonInferenceServer文档 1. 写在前面 上一篇文章对triton inference server进行了一个整体的介绍&#xff0c;解答了三个经典问题what, why, how。 这篇文章就开始转入实践&#xff0c; 从实践的角度整理Triton模型部署的全流程&#xff0c; 如果我有一个训…

华为 2024 届实习招聘——硬件-电源机试题(四套)

华为 2024 届实习招聘——硬件-电源机试题&#xff08;四套&#xff09; 部分题目分享&#xff0c;完整版带答案(有答案&#xff0c;答案非官方&#xff0c;未仔细校正&#xff0c;仅供参考&#xff09;&#xff08;共四套&#xff09; 获取&#xff08;WX:didadidadidida313&…

AcWing 796. 子矩阵的和——算法基础课题解

AcWing 796. 子矩阵的和 题目描述 输入一个 n 行 m 列的整数矩阵&#xff0c;再输入 q 个询问&#xff0c;每个询问包含四个整数 x1,y1,x2,y2&#xff0c;表示一个子矩阵的左上角坐标和右下角坐标。 对于每个询问输出子矩阵中所有数的和。 输入格式 第一行包含三个整数 n&…

Easy GIS .NET GMap.Net

Easy GIS .NET & GMap.Net .NET 环境下非常简单的GIS地图开发库。 Easy GIS .NET 一个简单的GIS 桌面应用程序&#xff0c;实现了地图瓦片加载、shapefile文件和csv文件加载渲染、地图坐标系统设置及转换等等基本功能&#xff0c;非常简单易用。 Easy GIS .NET is an o…

Linux CentOS 安装 MySQL 服务教程

Linux CentOS 安装 MySQL 服务教程 1. 查看系统和GNU C库(glibc)版本信息 1.1 查询机器 glibc 版本信息 glibc&#xff0c;全名GNU C Library&#xff0c;是大多数Linux发行版中使用的C库&#xff0c;为系统和应用程序提供核心的API接口。在Linux系统中&#xff0c;特别是在…

基于Springboot+Vue+Spring-Security+高德地图API的校园出行管理系统

1介绍 1.1编写目的 明确系统功能与操作流程&#xff0c;说明书提供了详细的系统功能描述和操作指南&#xff0c;使得用户能够了解如何通过系统申请请假、审批流程以及如何管理和监控请假记录等。 1.2文档范围 该文档的目的是解决整个项目系统中“做什么”的问题。对于开发技…

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…

YOLOv8 测试 5:Linux 中 Docker 部署 YOLOv8,Python 封装 API 接口,base64 图片处理

一、前言 记录时间 [2024-4-14] 系列文章简摘&#xff1a; Docker 学习笔记&#xff08;二&#xff09;&#xff1a;在 Linux 中部署 Docker&#xff08;Centos7 下安装 docker、环境配置&#xff0c;以及镜像简单使用&#xff09; API 接口简单使用&#xff08;二&#xff09;…

【HormonyOS4+NEXT】TypeScript基础语法详解

&#x1f64b;‍ 一日之际在于晨 ⭐本期内容&#xff1a;TypeScript基础语法详解 &#x1f3c6;系列专栏&#xff1a;鸿蒙HarmonyOS4NEXT&#xff1a;探索未来智能生态新纪元 文章目录 前言变量与类型函数类与接口类&#xff08;Class&#xff09;接口&#xff08;Interface&am…

Golang使用PGO优化程序性能

文章目录 参考文章PGO是什么使用PGO的好处PGO做了什么热函数内联什么是内联内联的好处Go默认的内联策略查看内联预算PGO的热函数内联 去虚拟化调用指令高速缓存 PGO有什么缺点可执行程序变大构建时间变长 PGO怎么使用典型的工作流程收集CPU配置文件生产环境启动PGO代码改动重新…

Go 自定义14位时间类型 yyyyMMddHHmmss

目录 功能 代码 功能 数据库或者接口时间类型&#xff0c;经常会使用14位的时间格式。每次都转换有点麻烦。可以自定义一个时间类型。 自定义类型需要实现json接口中的MarshalJSON与UnmarshalJSON两个函数&#xff0c;这样在做json编码解码时就会自动转为14位的时间格式了。…

Vue项目学习(一)-SQL闯关

Hello , 我是小恒不会java。今天来阅读一个Vue纯前端项目--SQL在线闯关 进步的方法除了文档书籍视频&#xff0c;学会阅读源代码&#xff0c;从代码中学会解决需求的方法也是必要的 已部署完成&#xff0c;在线体验&#xff1a;http://sql.yunduanjianzhan.cn 背景 简介 闯…

如何提升亚马逊店铺质量?住宅IP代理有何用处?

亚马逊作为全球最大的电子商务平台之一&#xff0c;吸引了无数卖家和买家参与其中。在这个竞争激烈的环境中&#xff0c;要想提升亚马逊店铺的质量和业绩&#xff0c;需要采取一系列有效的策略和工具。而住宅IP代理作为一个强大的网络工具&#xff0c;也在其中发挥着重要的作用…

最新的网易星球GEC挖矿系统修复版 章鱼星球挖矿系统源码 区块链虚拟币交易源码 基于ThinkPHP5开发

区块链系统介绍 2018.12.10更新增加聚合数据短信接口 2018.11.19更新增加短信宝接口 2018.08.17修复Linux系统搭建验证码不显示问题 2018.08.09修复后台某处溢出数据库账号密码BUG 2018.08.06修复票卷BUG 源码介绍&#xff1a; 区块链系统中用户共九个等级&#xff0c;依…

苹果系统如何使用CorelDRAW?coreldraw苹果版使用指南

有不少粉丝使用的是苹果的电脑或者笔记本&#xff0c;想要利用最新的M系列芯片带来的长续航便利&#xff0c;实现外出时进行创意设计的工作。 那如何才能在苹果系统使用CorelDRAW&#xff1f;2个方法分享给大家&#xff1a; 一、购买Mac版CorelDRAW 从2020版开始&#xff0c…

【热门话题】常见分类算法解析

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 常见分类算法解析1. 逻辑回归&#xff08;Logistic Regression&#xff09;2. 朴…

CSS文本属性与字体属性

目录 文本属性 文本颜色 文本对齐 修饰文本 文本缩进 行高 字体属性 字体系列 字体大小 字体粗细 字体样式 字体/文本综合属性写法 Chrome调试工具的使用 文本属性 文本颜色 在CSS中使用color 属性用于定义文本的颜色&#xff0c;使用background-color设置一个盒…

【教学类-50-06】20240410“数一数”4类星号图片制作PDF学具

作品展示&#xff1a; 背景需求&#xff1a; 前文遍历四个文件夹&#xff0c;分别将每个文件夹内的10个图片的左上角加入星号&#xff0c;显示难度系数 【教学类-50-05】20240410“数一数”4类图片添加“难度星号”-CSDN博客文章浏览阅读55次&#xff0c;点赞2次&#xff0c;…