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

[自制调试工具]利用模板函数打造通用调试工具

引言

上一篇文章 我们介绍了调式类工具,这篇文章我们补充一下

点击这里查看

在软件开发的过程中,调试是必不可少的环节。为了能更高效地定位和解决问题,我们常常需要在代码中插入一些调试信息,来输出变量的值、函数的执行状态等。传统的调试方式可能需要针对不同的数据类型编写不同的打印函数,这样会使代码变得冗长且难以维护。本文将介绍如何使用 C++ 的模板函数来实现一个通用的调试工具,它可以支持各种数据类型的打印,让调试变得更加便捷。

传统方式的局限性

在开始介绍模板函数之前,我们先来看一下传统的调试方式。假设我们有一个简单的 Debugger 类,用于打印不同类型的变量信息:

#include <iostream>
#include <string>class Debugger {
public:Debugger() {}~Debugger() {}// 打印整数信息void showInt(int num, std::string str = "") {std::cout << str << ": " << num << std::endl;}// 打印浮点数信息void showDouble(double num, std::string str = "") {std::cout << str << ": " << num << std::endl;}// 打印字符串信息void showString(const std::string& strValue, std::string str = "") {std::cout << str << ": " << strValue << std::endl;}
};int main() {int num = 10;double d = 3.14;std::string str = "Hello, World!";Debugger s;if (10 > 0) {num++;s.showInt(num, "if分支的num");s.showDouble(d, "if分支的d");s.showString(str, "if分支的str");} else {num = 11;s.showInt(num, "else分支的num");s.showDouble(d, "else分支的d");s.showString(str, "else分支的str");}return 0;
}

在这个例子中,我们为整数、浮点数和字符串分别编写了 showIntshowDouble 和 showString 函数。虽然这种方式可以实现我们的需求,但当需要支持更多的数据类型时,就需要不断地添加新的函数,代码会变得越来越复杂。

模板函数的解决方案

C++ 的模板函数可以帮助我们解决这个问题。模板函数允许我们编写一个通用的函数,它可以处理不同的数据类型,而不需要为每种类型都编写一个单独的函数。下面是使用模板函数重写的 Debugger 类:

#include <iostream>
#include <string>class Debugger {
public:Debugger() {}~Debugger() {}// 模板函数,支持各种类型template<typename T>void show(T value, std::string str = "") {std::cout << str << ": " << value << std::endl;}
};int main() {int num = 10;double d = 3.14;std::string str = "Hello, World!";Debugger s;if (10 > 0) {num++;s.show(num, "if分支的num");s.show(d, "if分支的d");s.show(str, "if分支的str");} else {num = 11;s.show(num, "else分支的num");s.show(d, "else分支的d");s.show(str, "else分支的str");}return 0;
}

在这个新的实现中,我们只需要定义一个模板函数 show,它可以接受任意类型的参数。当我们调用 show 函数时,编译器会根据传递的参数类型自动实例化相应的函数。这样,无论我们需要打印什么类型的变量,都只需要调用同一个函数,大大简化了代码。

模板函数的优势

  1. 代码复用:使用模板函数可以避免为每种数据类型编写重复的代码,提高了代码的复用性。
  2. 可扩展性:如果需要支持新的数据类型,只需要确保该类型支持 << 运算符,就可以直接使用 show 函数,无需修改代码。
  3. 简洁性:代码变得更加简洁,易于维护和阅读。

总结

通过使用 C++ 的模板函数,我们可以轻松地实现一个通用的调试工具,它可以支持各种数据类型的打印。这种方法不仅提高了代码的复用性和可扩展性,还让调试变得更加简单和高效。在实际开发中,我们可以根据需要对模板函数进行进一步的扩展,例如添加日志级别控制、文件输出等功能,以满足不同的调试需求。

希望本文能帮助你更好地理解和使用 C++ 的模板函数,让你的调试工作变得更加轻松愉快!

相关文章:

[自制调试工具]利用模板函数打造通用调试工具

引言 上一篇文章 我们介绍了调式类工具,这篇文章我们补充一下 点击这里查看 在软件开发的过程中&#xff0c;调试是必不可少的环节。为了能更高效地定位和解决问题&#xff0c;我们常常需要在代码中插入一些调试信息&#xff0c;来输出变量的值、函数的执行状态等。传统的调试…...

Python地理数据处理 28:基于Arcpy批量操作实现——按属性提取和分区统计

Arcpy批量操作 1. 批量按属性提取2. 批量分区统计&#xff08;最大值、最小值和像元个数等&#xff09; 1. 批量按属性提取 # -*- coding: cp936 -*- """ PROJECT_NAME: ArcPy FILE_NAME: batch_attribute_extract AUTHOR: JacksonZhao DATE: 2025/04/05 &qu…...

Mysql慢查询设置 和 建立索引

1 .mysql慢查询的设置 slow_query_log ON //或 slow_query_log_file /usr/local/mysql/data/slow.log long_query_time 2 修改后重启动mysql 1.1 查看设置后的参数 mysql> show variables like slow_query%; --------------------------------------------------…...

【Android】界面布局-相对布局RelativeLayout-例子

题目 完成下面相对布局&#xff0c;要求&#xff1a; 中间的button在整个屏幕的中央&#xff0c;其他的以它为基准排列。Hints&#xff1a;利用layout_toEndof,_toRightof,_toLeftof,_toStartof完成。 结果演示 代码实现 <?xml version"1.0" encoding"u…...

Spring Boot 中使用 Redis:从入门到实战

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…...

【ROS】 CMakeLists 文件详解

【ROS】 CMakeLists文件详解 前言标准的CMAKELIST.TXT文件的组成部分CMake 版本要求和项目名称指定编译器和设置构建规则查找 ROS 依赖消息和服务文件catkin_package设置头文件目录路径添加可执行文件的构建规则设置编译依赖关系&#xff08;构建顺序&#xff09;设置目标文件的…...

【每日算法】Day 17-1:位图(Bitmap)——十亿级数据去重与快速检索的终极方案(C++实现)

解锁海量数据处理的极致空间效率&#xff01;今日深入解析位图的核心原理与实战应用&#xff0c;从基础操作到分块优化&#xff0c;彻底掌握仅用1bit存储一个数据的压缩艺术。 一、位图核心思想 位图&#xff08;Bitmap&#xff09; 是一种通过比特位表示数据存在性的数据结构…...

7-1 素数求和(线性筛实现)

7-1 素数求和。 分数 10 中等 全屏浏览 切换布局 作者 魏英 单位 浙江科技大学 输入两个正整数m和n&#xff08;1<m<n<500&#xff09;统计并输出m和n之间的素数个数以及这些素数的和。 输入格式: 输入两个正整数m和n&#xff08;1<m<n<500&#xff0…...

NLP简介及其发展历史

自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能和计算机科学领域中的一个重要分支&#xff0c;致力于实现人与计算机之间自然、高效的语言交流。本文将介绍NLP的基本概念以及其发展历史。 一、什么是自然语言处理&#xff1f…...

ZKmall开源商城多云高可用架构方案:AWS/Azure/阿里云全栈实践

随着企业数字化转型的加速&#xff0c;云计算服务已成为IT战略中的核心部分。ZKmall开源商城作为一款高性能的开源商城系统&#xff0c;其在多云环境下的高可用架构方案备受关注。下面将结合AWS、Azure和阿里云三大主流云平台&#xff0c;探讨ZKmall的多云高可用架构全栈实践。…...

优化 Web 性能:处理非合成动画(Non-Composited Animations)

在 Web 开发中&#xff0c;动画能够增强用户体验&#xff0c;但低效的动画实现可能导致性能问题。Google 的 Lighthouse 工具在性能审计中特别关注“非合成动画”&#xff08;Non-Composited Animations&#xff09;&#xff0c;指出这些动画可能增加主线程负担&#xff0c;影响…...

Eliet Chat开发日志:信令服务器注册与通信过程

目录 1. 架构设计&#xff1a;信令服务器与客户端 2. 选择技术栈 3. 实现信令服务器 4. 客户端实现 5. 测试 6. 下一步计划 日期&#xff1a;2025年4月5日 今天的工作重点是实现两个设备通过信令服务器注册并请求对方公网地址信息&#xff0c;以便能够进行点对点通信。我…...

leetcode二叉树刷题调试不方便的解决办法

1. 二叉树不易构建 在leetcode中刷题时&#xff0c;如果没有会员就需要将代码拷贝到本地的编译器进行调试。但是leetcode中有一类题可谓是毒瘤&#xff0c;那就是二叉树的题。 要调试二叉树有关的题需要根据测试用例给出的前序遍历&#xff0c;自己构建一个二叉树&#xff0c;…...

颜色性格测试:探索你的内在性格色彩

颜色性格测试&#xff1a;探索你的内在性格色彩 在我们的日常生活中&#xff0c;颜色无处不在&#xff0c;而我们对颜色的偏好往往能反映出我们内在的性格特质。今天我要分享一个有趣的在线工具 —— 颜色性格测试&#xff0c;它能通过你最喜欢的颜色来分析你的性格倾向。 &…...

hashtable遍历的方法有哪些

在 Java 中&#xff0c;遍历 Hashtable&#xff08;或其现代替代品 HashMap&#xff09;有多种方式&#xff0c;以下是 6 种常用方法的详细说明和代码示例&#xff1a; 1. 使用 keySet() 增强 for 循环 Hashtable<String, Integer> table new Hashtable<>(); // …...

CMake学习--Window下VSCode 中 CMake C++ 代码调试操作方法

目录 一、背景知识二、使用方法&#xff08;一&#xff09;安装扩展&#xff08;二&#xff09;创建 CMake 项目&#xff08;三&#xff09;编写代码&#xff08;四&#xff09;配置 CMakeLists.txt&#xff08;五&#xff09;生成构建文件&#xff08;六&#xff09;开始调试 …...

浅谈ai - Activation Checkpointing - 时间换空间

前言 曾在游戏世界挥洒创意&#xff0c;也曾在前端和后端的浪潮间穿梭&#xff0c;如今&#xff0c;而立的我仰望AI的璀璨星空&#xff0c;心潮澎湃&#xff0c;步履不停&#xff01;愿你我皆乘风破浪&#xff0c;逐梦星辰&#xff01; Activation Checkpointing&#xff08;激…...

提高MCU的效率方法

要提高MCU(微控制器单元)的编程效率,需要从硬件特性、代码优化、算法选择、资源管理等多方面入手。以下是一些关键策略: 1. 硬件相关优化 时钟与频率: 根据需求选择合适的时钟源(内部/外部振荡器),避免过高的时钟频率导致功耗浪费。关闭未使用的外设时钟(如定时器、UA…...

5G从专家到小白

文章目录 第五代移动通信技术&#xff08;5G&#xff09;简介应用场景 数据传输率带宽频段频段 VS 带宽中低频&#xff08;6 GHz以下&#xff09;&#xff1a;覆盖范围广、穿透力强高频&#xff08;24 GHz以上&#xff09;&#xff1a;满足在热点区域提升容量的需求毫米波热点区…...

神经网络入门:生动解读机器学习的“神经元”

神经网络作为机器学习中的核心算法之一&#xff0c;其灵感来源于生物神经系统。在本文中&#xff0c;我们将带领大家手把手学习神经网络的基本原理、结构和训练过程&#xff0c;并通过详细的 Python 代码实例让理论与实践紧密结合。无论你是编程新手还是机器学习爱好者&#xf…...

web漏洞靶场学习分享

靶场&#xff1a;pikachu靶场 pikachu漏洞靶场漏洞类型: Burt Force(暴力破解漏洞)XSS(跨站脚本漏洞)CSRF(跨站请求伪造)SQL-Inject(SQL注入漏洞)RCE(远程命令/代码执行)Files Inclusion(文件包含漏洞)Unsafe file downloads(不安全的文件下载)Unsafe file uploads(不安全的文…...

vue watch和 watchEffect

在 Vue 3 中&#xff0c;watch 和 watchEffect 是两个用于响应式地监听数据变化并执行副作用的 API。它们在功能上有一些相似之处&#xff0c;但用途和行为有所不同。以下是对 watch 和 watchEffect 的详细对比和解释&#xff1a; 1. watch watch 是一个更通用的 API&#xf…...

函数和模式化——python

一、模块和包 将一段代码保存为应该扩展名为.py 的文件&#xff0c;该文件就是模块。Python中的模块分为三种&#xff0c;分别为&#xff1a;内置模块、第三方模块和自定义模块。 内置模块和第三方模块又称为库内置模块&#xff0c;有 python 解释器自带&#xff0c;不用单独安…...

Python解决“数字插入”问题

Python解决“数字插入”问题 问题描述测试样例解题思路代码 问题描述 小U手中有两个数字 a 和 b。第一个数字是一个任意的正整数&#xff0c;而第二个数字是一个非负整数。她的任务是将第二个数字 b 插入到第一个数字 a 的某个位置&#xff0c;以形成一个最大的可能数字。 你…...

Go语言的嵌入式网络

Go语言的嵌入式网络 引言 在当今快速发展的互联网时代&#xff0c;嵌入式系统和网络技术的结合变得越来越普遍。嵌入式系统是指嵌入到设备中以实现特定功能的计算机系统&#xff0c;它们通常具有资源有限的特点。随着物联网&#xff08;IoT&#xff09;的兴起&#xff0c;嵌入…...

Dart 语法

1. 级联操作符 … var paint Paint()..color Colors.black..strokeCap StrokeCap.round..strokeWidth 5.0;2. firstWhereOrNull 3. 隐藏或导入部分组件 // Import only foo. import package:lib1/lib1.dart show foo;// Import all names EXCEPT foo. import package:lib…...

MCP over MQTT:EMQX 开启物联网 Agentic 时代

前言 随着 DeepSeek 等大语言模型&#xff08;LLM&#xff09;的广泛应用&#xff0c;如何找到合适的场景&#xff0c;并基于这些大模型构建服务于各行各业的智能体成为关键课题。在社区中&#xff0c;支持智能体开发的基础设施和工具层出不穷&#xff0c;其中&#xff0c;Ant…...

ACM代码模式笔记

系列博客目录 文章目录 系列博客目录1.换行符 1.换行符 nextInt()、nextDouble() 等不会消耗换行符&#xff1a; 当使用 nextInt() 或 nextDouble() 读取数字时&#xff0c;它只读取数字部分&#xff0c;不会消耗掉输入后的换行符。 nextLine() 会读取并消耗换行符&#xff1a…...

相干光信号处理的一些基础知识

1. 逆琼斯矩阵问题 逆琼斯矩阵方法常用于逆向补偿由光学系统或传输信道&#xff08;如光纤&#xff09;引入的偏振态&#xff08;SOP, State of Polarization&#xff09;畸变。 1.1 琼斯向量 任意偏振光可用二维复数向量表示&#xff1a; E [ E x E y ] [ ∣ E x ∣ e i…...

WiFi加密协议

目录 1. 认证(Authentication)‌ ‌1.1 开放系统认证(Open System Authentication)‌ 1.2 共享密钥认证(Shared Key Authentication)‌ ‌1.3 802.1X/EAP认证(企业级认证)‌ ‌2. 关联(Association)‌ ‌3. 加密协议(Security Handshake)‌ ‌整体流程总结‌…...