C++学习笔记----8、掌握类与对象(二)---- 成员函数的更多知识(2)

news2024/10/2 11:13:37

3、成员函数重载

        你已经注意到在类中可以写多个构造函数,所有的都有同样的名字。这些构造函数的不同仅仅在于其参数的数目与/或类型。在c++中任何成员函数或函数可以做同样的事情。特别地,可以重构一个函数或成员函数名,通过使用它来用于多个函数,只要参数的数目和/或类型不同。例如,在SpreadsheetCell类中,可以将setString()与setValue重命名为set()。类定义现在看起来像这样:

export class SpreadsheetCell
{
public:
    void set(double value);
    void set(std::string_view value);
    // Omitted for brevity
};

        set()成员函数的实现保持不变。当写代码调用set()时,编译器决定调用哪个实例,是基于传入的参数:如果传入参数是string_view,编译器会调用string_view实例;如果传入的是一个double,编译器为调用double实例。这叫做调用重载解析。

        你可能会想对getValue()与getString()做同样的事情:把它们重命名为get()。然而,这却不好使。c++不允许只基于返回类型来重载一个成员函数,因为在很多情况下编译器无法决定调用成员函数的实例。例如,如果成员函数的返回值没有被获取,编译器就不知道你想调用哪个成员函数的实例。

3.1、基于const重载

        可以基于const重载成员函数。也就是说,可以写两个同名同参数的成员函数,一个声明为const,而另一个不是。如果你有一个const对象编译器调用const成员函数,如果你有一个non-cost对象它会调用non-const重载。写这校招的两个重载成员函数可能会带来代码重复,因为,通常情况下,const与non-const重载的实现是一样的。你知道的,应该尽可能地避免代码重复,即使是只有几行。要遵循我们以前讨论过的DRY(不要重复自己)原则,使以后的代码维护容易些。例如,想像一下,几个月或者几年后,需要对重复代码做一点小小的变更。当这样做的时候,需要记住要对所有出现重复代码的地方进行同样的修改。是不是很烦人?

        下面一节会提供两个解决方案来避免代码重复,当写这样重载成员函数的时候。

3.1.1、Scott Meyers的const_cast模式

        为了避免代码重复,可以使用Scott Meyers的const_cast()模式。例如,Spreadsheet类有一个叫做getCellAt()的成员函数返回一个reference-to-non-const给到SpreadsheetCell。可以加一个const重载返回一个reference-to-const给到SpreadsheetCell,如下:

export class Spreadsheet
{
public:
    SpreadsheetCell& getCellAt(std::size_t x, std::size_t y);
    const SpreadsheetCell& getCellAt(std::size_t x, std::size_t y) const;
    // Code omitted for brevity.
};

        Scott Meyer的const_cast()模式应用const重载就像你通常做的那样,通过传递调用给const重载使用合适的转化来实现non-const重载,如下:

const SpreadsheetCell& Spreadsheet::getCellAt(size_t x, size_t y) const
{
    verifyCoordinate(x, y);
    return m_cells[x][y];
}

SpreadsheetCell& Spreadsheet::getCellAt(size_t x, size_t y)
{
    return const_cast<SpreadsheetCell&>(as_const(*this).getCellAt(x, y));
}

        模式首先使用std::as_const()将*this(一个Spreadsheet&)转化为一个const Spreadsheet&。接着,调用getCellAt()的const重载,它返回一个const SpreadsheetCell&。然后用const_cast()将其转化为一个non-const SpreadsheetCell&。

        有了这两个getCellAt()重载,现在可以对const与non-const Spreadsheet对象调用getCellAt()了:

Spreadsheet sheet1 { 5, 6 };
SpreadsheetCell& cell1 { sheet1.getCellAt(1, 1) };
const Spreadsheet sheet2 { 5, 6 };
const SpreadsheetCell& cell2 { sheet2.getCellAt(1, 1) };

3.1.2、私有的辅助成员函数

        另一个避免代码重复的选项是在实现const与non-const重载时用non-const返回类型做一个private const辅助成员函数。const与non-const重载成员函数都调用这个辅助函数。例如,对于上一节中的getCellAt()重载,可以添加一个getCellAtHelper()如下:

export class Spreadsheet
{
public:
    SpreadsheetCell& getCellAt(std::size_t x, std::size_t y);
    const SpreadsheetCell& getCellAt(std::size_t x, std::size_t y) const;
    // Code omitted for brevity.

private:
    SpreadsheetCell& getCellAtHelper(std::size_t x, std::size_t y) const;
};

        下面是实现:

SpreadsheetCell& Spreadsheet::getCellAt(size_t x, size_t y)
{
    return getCellAtHelper(x, y);
}

const SpreadsheetCell& Spreadsheet::getCellAt(size_t x, size_t y) const
{
    return getCellAtHelper(x, y);
}

SpreadsheetCell& Spreadsheet::getCellAtHelper(size_t x, size_t y) const
{
    verifyCoordinate(x, y);
    return m_cells[x][y];
}

3.2、显式删除重载

        重载成员函数可以被显式删除,这样就可以禁止使用特别的参数来调用成员函数。例如,SpreadsheetCell类有一个成员函数setValue(double)可以被调用如下:

SpreadsheetCell cell;
cell.setValue(1.23);
cell.setValue(123);

        第三行,编译器将整数(123)转化为double,然后调用setValue(double)。如果,基于某种原因,你不想setValue()用整数调用,可以显式地删除setValue()的整型数重载:

export class SpreadsheetCell
{
public:
    void setValue(double value);
    void setValue(int) = delete;
};

        有了这个改变,意图用整型数调用setValue()就会被编译器标记成一个错误。

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

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

相关文章

微信小程序操作蓝牙

主要流程&#xff1a; 1.初始化蓝牙适配器openBluetoothAdapter&#xff0c;如果不成功就onBluetoothAdapterStateChange监听蓝牙适配器状态变化事件 2.startBluetoothDevicesDiscovery开始搜寻附近的蓝牙外围设备 3.onBluetoothDeviceFound监听寻找到新设备的事件&#xff0c;…

制造业该如何应用大数据?

​收到一位朋友私信&#xff0c;提问“制造业该如何应用大数据”&#xff1f;我觉得这个问题非常好&#xff0c;而且这也将是未来机械专业领域的一个重要突破口。 而传统制造企业与计算机、互联网行业的最佳结合点就在这里。 如果你没有真正的去实施过一个企业的信息化项目&a…

【重学 MySQL】四十五、数据库的创建、修改与删除

【重学 MySQL】四十五、数据库的创建、修改与删除 一条数据存储的过程数据输入数据验证数据处理数据存储数据持久化反馈与日志注意事项 标识符命名规则基本规则长度限制保留字与特殊字符命名建议示例 MySQL 中的数据类型创建数据库创建数据库时指定字符集和排序规则 查看数据库…

[Linux]开发环境搭建

RPM和YUM 安装JDK 安装Tomcat 安装IDEA 安装MySql

代码随想录算法训练营Day20 | 235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

目录 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点 235. 二叉搜索树的最近公共祖先 题目 235. 二叉搜索树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先…

Yocto - 使用Yocto开发嵌入式Linux系统_05 认识Bitbake工具

Meeting the BitBake Tool 通过本章&#xff0c;我们将开始学习 Yocto 项目引擎如何在幕后工作的旅程。正如每一段旅程一样&#xff0c;沟通是至关重要的&#xff0c;因此我们需要理解 Yocto 项目工具所使用的语言&#xff0c;并学习如何充分利用这些工具来实现我们的目标。 Wi…

网页前端开发之Javascript入门篇(3/9):条件控制

Javascript条件控制 什么是条件控制&#xff1f; 答&#xff1a;其概念跟 Python教程 介绍的一样&#xff0c;只是语法上有所变化。 参考流程图如下&#xff1a; 其对应语法&#xff1a; var button false; // 开关状态 console.log("检查开关.."); if(bu…

一文掌握Harbor镜像同步公有云镜像仓库实践

一文掌握Harbor镜像同步公有云镜像仓库实践 目录 1 引言2 概念 2.1 Harbor2.2 阿里云的镜像仓库ACR2.3 华为云的镜像仓库SWR2.4 Harbor复制管理同步镜像 2.4.1 复制管理的工作原理 2.5 Harbor同步镜像到公有云镜像仓库的优势 3 实验&#xff1a;通过Harbor 将容器镜像同步到公…

刷题系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;知识点管理&#xff0c;科目类型管理&#xff0c;试题管理&#xff0c;试卷管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;我的 开发系统&#…

vulnhub-W34kn3ss 1靶机

vulnhub&#xff1a;https://www.vulnhub.com/entry/w34kn3ss-1,270/ 导入靶机&#xff0c;扫描 靶机开在192.168.81.7.扫描端口 扫到三个端口&#xff0c;存在网站服务&#xff0c;访问 80端口没什么东西&#xff0c;443似乎访问到的是同一个界面&#xff0c;这种情况下一般是…

Visual Studio C# 处理和修复 WinRiver II 测量项目 MMT 文件错误

Visual Studio C# 处理和修复 WinRiver II 测量项目 MMT 文件错误 前言一、WinRiver II 测量项目 MMT 文件的结构二、WinRiver II 无法打开或操作测量项目 MMT 文件2.1 无法载入船测多线法测量文件2.2 可以载入测验项目 MMT 文件&#xff0c;但 ADCP 后处理软件无法写入信息2.3…

基于SpringBoot+vue的监理公司信息化管理系统设计与实现

目录 1. 系统概述 2. 技术选型 3. 系统模块设计 3.1 收入支出管理 3.2 合同管理 3.3 财务统计 3.4 甲方乙方公告 4. 安全性考虑 5. 效果展示和示例代码 6. 总结 1. 系统概述 随着经济的快速发展和社会的进步&#xff0c;建筑行业作为国民经济的重要支柱产业之…

[MAUI]数据绑定和MVVM:MVVM的属性验证

一、MVVM的属性验证案例 Toolkit.Mvvm框架中的ObservableValidator类,提供了属性验证功能,可以使用我们熟悉的验证特性对属性的值进行验证,并将错误属性提取和反馈给UI层。以下案例实现对UI层的姓名和年龄两个输入框,进行表单提交验证。实现效果如下所示 View<ContentP…

医院体检管理系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;体检分类管理&#xff0c;体检套餐管理&#xff0c;体检预约管理&#xff0c;体检报告管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;体检套餐&a…

Jetson 开发系列:Orin Nano 开箱!一款强大的嵌入式物联网开发板

边缘计算作为 AI 的一个重要应用场景&#xff0c;面临着前所未有的机遇与挑战。 谈及 AI&#xff0c;自然绕不开 NVIDIA 的产品&#xff1a; 其中&#xff0c;Jetson 系列均为 AIoT 设备打造&#xff0c;功耗低是其最大的特点。以我手头的 Jetson Ori Nano 为例&#xff0c;满…

一文彻底搞懂多模态 - 基础术语+基础知识+多模态学习

文章目录 技术交流基本术语一、数据采集与表示二、数据处理与融合三、学习与推理 基础知识一、传统机器学习二、深度学习三、优化算法四、应用领域 多模态学习一、模态表示二、多模态融合图片 三、跨模态对齐 最近这一两周看到不少互联网公司都已经开始秋招发放Offer。 不同以…

【MAUI】View和ViewModel的关联方式

方式一:创建ViewModel对象: 在View中,通过设置BindingContext为ViewModel对象,即可进行绑定。如下所示: <ContentPage......xmlns:vm="clr-namespace:MauiApp8.ViewModels"><

多模态RAG实现

在标准 RAG 中&#xff0c;输入文档包含文本数据。LLM 利用上下文学习&#xff0c;通过检索与所提查询上下文相匹配的文本文档块来提供更相关、更准确的答案。 但是&#xff0c;如果文档包含图像、表格、图表等以及文本数据&#xff0c;该怎么办&#xff1f; 不同的文档格式包…

基于 Qwen2.5-0.5B 微调训练 Ner 命名实体识别任务

一、Qwen2.5 & 数据集 Qwen2.5 是 Qwen 大型语言模型的最新系列&#xff0c;参数范围从 0.5B 到 72B 不等。 对比 Qwen2 最新的 Qwen2.5 进行了以下改进&#xff1a; 知识明显增加&#xff0c;并且大大提高了编码和数学能力。在指令跟随、生成长文本&#xff08;超过 8K…

【Maven】依赖管理,Maven仓库,Maven核心功能

Maven 是一个项目管理工具&#xff0c;基于 POM&#xff08;Project Object Model&#xff0c;项目对象模型&#xff09;的概念&#xff0c;Maven 可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件 大白话&#xff1a;Maven 是一个项目管理工…