当前位置: 首页 > news >正文

C++讲解---通过转换函数和运算符函数直接调用类的对象

本文将使用计数器类作为案例,详细讲解如何通过转换函数和运算符函数让类的对象能够像内置类型一样直接使用。
现在我们有一个基础版本的计数器如下:
版本1:基础计数器类

#include <iostream>class Counter {unsigned cnt = 0;
public:// 基础功能void increment() { if (cnt < UINT_MAX) cnt++; }void decrement() { if (cnt > 0) cnt--; }unsigned value() const { return cnt; }
};// 使用示例
void demo_v1() {Counter c;c.increment();c.decrement();std::cout << "计数器值: " << c.value() << "\n"; // 输出: 2
}

1. 转换函数详解

  • 什么是转换函数?
  • 转换函数允许类对象在需要特定类型时自动转换为该类型。

格式为:

operator target_type() const;

那么,在这个计数器类中,可以这样写:

operator unsigned() const { return cnt; }

也就是说,直接把基础版本中的构造函数中的这行代码进行了替换:

 unsigned value() const { return cnt; }

从而,在使用类的时候,每次都需要调用函数 increment,decrement:

 	Counter c;c.increment();c.decrement();

变为了直接使用 c本身:

	Counter c;std::cout << c; // 输出对象,自动转换为unsigned输出unsigned total = c + 5; // 参与运算,自动转换为unsigned后相加if (c > 10) { // 自动转换为unsigned后比较// 参与条件判断
}

2. 运算符函数详解

  • 什么是运算符函数?
  • 运算符函数允许类对象使用标准运算符(如++, --, !等)。

格式为:

return_type operator op (parameters);

那么,在这个计数器类中,如果想要替代函数 increment,及函数value的返回值,可以这样写:

// 前置递增
Counter& operator++() {
// 实现递增逻辑if (cnt < UINT_MAX) cnt++;// 返回自身的引用return *this;
}// 后置递增
Counter operator++(int) {Counter temp = *this;// 保存原始值++(*this);// 调用前置递增return temp;// 返回原始值
}

也就是替代了原函数中的这些语句,并且使得自增自减更加的精细了:

  void increment() { if (cnt < UINT_MAX) cnt++; }unsigned value() const { return cnt; }

同理,decreme函数也可以这样写。

那么升级后的计数器类是这样的:

版本2:支持直接调用的计数器类

#include <iostream>
#include <climits>class Counter {unsigned cnt = 0;
public:// 转换函数:Counter -> unsignedoperator unsigned() const { return cnt; }// 运算符函数:逻辑非bool operator!() const { return cnt == 0; }//在这里判断输入的cnt是否为0,如果为0,则不执行const函数。// 运算符函数:前置递增Counter& operator++() {if (cnt < UINT_MAX) cnt++;return *this;}// 运算符函数:后置递增Counter operator++(int) {Counter temp = *this;++(*this);return temp;}// 运算符函数:前置递减Counter& operator--() {if (cnt > 0) cnt--;return *this;}// 运算符函数:后置递减Counter operator--(int) {Counter temp = *this;--(*this);return temp;}
};// 使用示例
void demo_v2() {Counter c;// 直接使用递增运算符++c; // 前置递增c++; // 后置递增// 直接输出对象(调用转换函数)std::cout << "计数器值: " << c << "\n"; // 输出: 2// 直接参与运算(调用转换函数)unsigned total = c * 10;std::cout << "总数值: " << total << "\n"; // 输出: 20// 使用逻辑非运算符if (!c) {std::cout << "计数器为零\n";} else {std::cout << "计数器不为零\n"; // 输出此项}
}
http://www.dtcms.com/a/323457.html

相关文章:

  • Horse3D引擎研发笔记(三):使用QtOpenGL的Shader编程绘制彩色三角形
  • Aurora设计注意问题
  • 【递归、搜索和回溯】FloodFill 算法介绍及相关例题
  • 11. 为什么要用static关键字
  • 香橙派 RK3588 部署千问大模型 Qwen2-VL-2B 多轮交互式对话
  • 【工具】Python多环境管理
  • ubuntu安装ollama流程
  • Day 8: 深度学习综合实战与进阶技术 - 从优化到部署的完整流程
  • Java+Vue打造的采购招投标一体化管理系统,涵盖招标、投标、开标、评标全流程,功能完备,附完整可二次开发的源码
  • 数据结构day06
  • 102-基于Spark的招聘数据预测分析推荐系统
  • 物质和暗物质形成机制
  • 【排序算法】④堆排序
  • 工具箱许愿墙项目发布
  • AI_RAG
  • 复现论文关于3-RPRU并联机器人运动学建模与参数优化设计
  • 机器翻译实战:使用Gensim训练中英文词向量模型及可视化
  • Android之gradle和gradlew命令编译项目总结
  • 消息队列核心功能和消息队列做异步的优势
  • C++:继承[下篇]
  • Vue 使用element plus组件库提示doesn‘t work properly without JavaScript enabled
  • [ MySQL 数据库 ] 多表关联查询
  • STM32HAL库 -- 10.DMA外设实战(UART串口+DMA读取传感器数据)
  • Tangram官网教程
  • Qt Graphics View框架概述
  • 夺宝奇兵 古老之圈 送修改器(The Great Circle)免安装中文版
  • openvela之STM32开发板部署
  • 力扣(轮转数组)
  • 智慧水务漏检率↓75%:陌讯水下视觉监测方案实战解析
  • 北京天津唐山廊坊沧州打捞日记