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

模板泛化类如何卸载释放内存

CustomWidget::~CustomWidget() {for (size_t i = 0; i < buttonManager.registerItem.size(); ++i) {delete buttonManager.registerItem(exitButton);}
}
以上该怎么写删除对象操作,类如下:template <typename T>
class GenericManager {
public:using ConditionFunc = std::function<bool(const T&, const QPoint&)>;using ActionFunc = std::function<void(QPainter&, const T&, bool)>;GenericManager() {}void registerItem(T* item) {int count = items.count();qWarning("Inserting at index %d, current count: %d", count, count);items.insert(count, item);}void processItems(QPainter& bufferPainter, QMouseEvent* event, QWidget* widget, ConditionFunc conditionFunc, ActionFunc actionFunc) {QPoint cursorPos = event ? event->pos() : widget->mapFromGlobal(QCursor::pos());// 将 i 的类型改为 size_tfor (size_t i = 0; i < items.count(); ++i) {T* item = items.at(i);if (item) {qWarning("Inserting at index");bool shouldHighlight = conditionFunc(*item, cursorPos);actionFunc(bufferPainter, *item, shouldHighlight);}}}private:QPtrVector<T> items;
};

使用模板来泛化类,如何增加删除对象的处理,增加代码如下:

 // 提供一个公共方法来获取 items 的数量size_t getItemCount() const {return items.count();}// 提供一个公共方法来获取指定索引的元素T* getItemAt(size_t index) const {if (index < items.count()) {return items.at(index);}return nullptr;}

析构函数删除对象:

CustomWidget::~CustomWidget() {// 遍历 GenericManager 中的 items 并释放内存for (size_t i = 0; i < buttonManager.getItemCount(); ++i) {ButtonInfo* item = buttonManager.getItemAt(i);if (item) {delete item;}}
}

注意不能用T* item= buttonManager.getItemAt(i);这样, CustomWidget 的析构函数中正确释放内存

T 是未定义的标识符,因为 T 是 GenericManager 类模板的模板参数,在 CustomWidget 类的作用域内并没有这个类型定义。而在 CustomWidget 里使用的是 GenericManager<ButtonInfo>,所以应该明确使用 ButtonInfo* 来接收 getItemAt 方法返回的指针。

调用方式:

void CustomWidget::paintEvent(QPaintEvent *event) {bufferPixmap = QPixmap(size());//bufferPixmap.fill(Qt::transparent);QPainter bufferPainter(&bufferPixmap);// drawBackgroundAndBorder(bufferPainter);buttonManager.processItems(bufferPainter, nullptr, this, [](const ButtonInfo& button, const QPoint& cursorPos) {return button.rect.contains(cursorPos);},[this](QPainter& painter, const ButtonInfo& button, bool isHighlighted) { // 添加 this 到捕获列表QRect drawRect(button.rect.x(), button.rect.y(), button.rect.width(), button.rect.height());qWarning("Draw rect: (%d, %d, %d, %d)", drawRect.x(), drawRect.y(), drawRect.width(), drawRect.height());QImage img;img.loadFromData(isHighlighted ? button.highlight_png : button.normal_png,isHighlighted ? button.highlight_png_size : button.normal_png_size,"PNG");if (img.isNull()) {// 使用 qWarning 替代 qDebugqWarning("Failed to load image");}// 如果 Qt 版本支持,可以保留下面这行// painter.setRenderHint(QPainter::Antialiasing); this->simulateLinearGradient(painter, drawRect, QColor(15, 10, 60), QColor(7, 69, 111));painter.drawImage(drawRect, img);});QPainter painter(this);painter.drawPixmap(0, 0, bufferPixmap);
}

注意,可以随意设置条件和绘制内容,conditionFun本例是lambda表达式 return button.rect.contains(cursorPos);

绘制结果简单一句img.loadFromData(isHighlighted ? button.highlight_png : button.normal_png,
                             isHighlighted ? button.highlight_png_size : button.normal_png_size,
                             "PNG");

这样充分利用C++的新特性,代码变得简单清晰

 

在 C++ 的 Lambda 表达式中,方括号 [] 部分被称为捕获列表,它用于指定 Lambda 表达式可以访问哪些外部变量。捕获列表不同的写法有不同的作用,下面详细解释为什么在你的代码里一个 Lambda 用 [],另一个用 [this]

1. [] 捕获列表

[](const ButtonInfo& button, const QPoint& cursorPos) {return button.rect.contains(cursorPos);
}

这里使用 [] 表示该 Lambda 表达式不捕获任何外部变量。这个 Lambda 表达式作为 conditionFunc 传递给 buttonManager.processItems 方法,它只依赖于传入的参数 button 和 cursorPos,不需要访问外部作用域中的任何变量,所以捕获列表为空。它的功能仅仅是判断鼠标位置 cursorPos 是否在按钮的矩形区域 button.rect 内。

2. [this] 捕获列表

[this](QPainter& painter, const ButtonInfo& button, bool isHighlighted) {QRect drawRect(button.rect.x(), button.rect.y(), button.rect.width(), button.rect.height());qWarning("Draw rect: (%d, %d, %d, %d)", drawRect.x(), drawRect.y(), drawRect.width(), drawRect.height());QImage img;img.loadFromData(isHighlighted ? button.highlight_png : button.normal_png,isHighlighted ? button.highlight_png_size : button.normal_png_size,"PNG");if (img.isNull()) {qWarning("Failed to load image");}this->simulateLinearGradient(painter, drawRect, QColor(15, 10, 60), QColor(7, 69, 111));painter.drawImage(drawRect, img);
}

这里使用 [this] 表示该 Lambda 表达式捕获当前对象的指针 this。在这个 Lambda 表达式中,调用了 this->simulateLinearGradient 方法,这是当前对象 CustomWidget 的一个成员函数。为了能够访问当前对象的成员函数和成员变量,需要通过 this 指针,所以在捕获列表中指定 this。这样,Lambda 表达式就可以在其内部调用当前对象的方法和访问成员变量了。

总结

  • []:不捕获任何外部变量,Lambda 表达式只能使用其参数列表中的变量。
  • [this]:捕获当前对象的指针,Lambda 表达式可以访问当前对象的成员函数和成员变量。

通过合理使用捕获列表,可以让 Lambda 表达式根据需要访问外部作用域中的变量,从而实现更灵活的功能

相关文章:

模板泛化类如何卸载释放内存

CustomWidget::~CustomWidget() {for (size_t i 0; i < buttonManager.registerItem.size(); i) {delete buttonManager.registerItem(exitButton);} } 以上该怎么写删除对象操作&#xff0c;类如下&#xff1a;template <typename T> class GenericManager { public…...

MFC结构体数据文件读写实例

程序功能将结构体内数组数据写入文件和读出 2Dlg.h中代码: typedef struct Student {int nNum[1000];float fScore;CString sss;}stu; class CMy2Dlg : public CDialog { // Construction public:CMy2Dlg(CWnd* pParent NULL); // standard constructorstu stu1; ... } 2Dl…...

jemalloc 5.3.0的tsd模块的源码分析

一、背景 在主流的内存库里&#xff0c;jemalloc作为android 5.0-android 10.0的默认分配器肯定占用了非常重要的一席之地。jemalloc的低版本和高版本之间的差异特别大&#xff0c;低版本的诸多网上整理的总结&#xff0c;无论是在概念上和还是在结构体命名上在新版本中很多都…...

03-机器学习-数据获取

一、流行机器学习数据集 主流机器学习数据集汇总 数据集名称描述来源MNIST手写数字图像数据集&#xff0c;由美国人口普查局员工书写。MNIST官网ImageNet包含数百万张图像&#xff0c;用于图像分类和目标检测。ImageNet官网AudioSet包含YouTube音频片段&#xff0c;用于声音分…...

编程题-最长的回文子串(中等)

题目&#xff1a; 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#xff1a;"bab" 解释&#xff1a;"aba" 同样是符合题意的答案。示例 2&#xff1a; 输入&#xff1a;s &…...

爱书爱考平台说明

最近我开发了一个综合性的考试平台&#xff0c;内容包括但不限于职业资格证考试、成人教育、国家公务员考试等内容。目前1.0版本已经开发完成&#xff0c;其他的功能陆续完善中。 微信小程序搜索"爱书爱考" 微信小程序图标如下图: 目前维护了java相关的面试题的考题…...

doris: MAP数据类型

MAP<K, V> 表示由K, V类型元素组成的 map&#xff0c;不能作为 key 列使用。 目前支持在 Duplicate&#xff0c;Unique 模型的表中使用。 K, V 支持的类型有&#xff1a; BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, FLOAT, DOUBLE, DECIMAL, DECIMALV3, DAT…...

JUC--ConcurrentHashMap底层原理

ConcurrentHashMap底层原理 ConcurrentHashMapJDK1.7底层结构线程安全底层具体实现 JDK1.8底层结构线程安全底层具体实现 总结JDK 1.7 和 JDK 1.8实现有什么不同&#xff1f;ConcurrentHashMap 中的 CAS 应用 ConcurrentHashMap ConcurrentHashMap 是一种线程安全的高效Map集合…...

Sklearn 中的逻辑回归

逻辑回归的数学模型 基本模型 逻辑回归主要用于处理二分类问题。二分类问题对于模型的输出包含 0 和 1&#xff0c;是一个不连续的值。分类问题的结果一般不能由线性函数求出。这里就需要一个特别的函数来求解&#xff0c;这里引入一个新的函数 Sigmoid 函数&#xff0c;也成…...

Spring Boot 自定义属性

Spring Boot 自定义属性 在 Spring Boot 应用程序中&#xff0c;application.yml 是一个常用的配置文件格式。它允许我们以层次化的方式组织配置信息&#xff0c;并且比传统的 .properties 文件更加直观。 本文将介绍如何在 Spring Boot 中读取和使用 application.yml 中的配…...

1.2第1章DC/DC变换器的动态建模-1.2Buck-Boost 变换器的交流模型--电力电子系统建模及控制 (徐德鸿)--读书笔记

1.2 Buck-Boost 变换器的交流模型 Buck- Boost变换器是一种典型的DC/DC变换器&#xff0c;具有升压和降压功能其输出电压的极性与输入电压相反&#xff0c;见图1-4a。当电感L的电流i(t)连续时一个开关周期可以分为两个阶段。在阶段1&#xff0c;开关在位置1时&#xff0c;即&am…...

数据结构:二叉树—面试题(一)

目录 1、相同的树 2、另一棵树的子树 3、翻转二叉树 4、平衡二叉树 5、对称二叉树 6、二叉树遍历 7、二叉树的分层遍历 1、相同的树 习题链接https://leetcode.cn/problems/same-tree/description/ 描述&#xff1a; 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一…...

DDD 和 TDD

领域驱动设计&#xff08;DDD&#xff09; DDD 是一种软件开发方法&#xff0c;强调通过与领域专家的密切合作来构建一个反映业务逻辑的模型。其核心思想是将业务逻辑和技术实现紧密结合&#xff0c;以便更好地解决复杂的业务问题。 DDD 的关键概念&#xff1a; 1. 领域模型 …...

LangChain概述

文章目录 为什么需要LangChainLLM应用开发的最后1公里LangChain的2个关键词LangChain的3个场景LangChain的6大模块 为什么需要LangChain 首先想象一个开发者在构建一个LLM应用时的常见场景。当你开始构建一个新项目时&#xff0c;你可能会遇到许多API接口、数据格式和工具。对于…...

Java基于SSM框架的互助学习平台小程序【附源码、文档】

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…...

lightweight-charts-python 包 更新 lightweight-charts.js 的方法

lightweight-charts-python 是 lightweight-charts.js 的 python 包装&#xff0c;非常好用 lightweight-charts 更新比较频繁&#xff0c;导致 lightweight-charts-python 内置的 lightweight-charts 经常不是最新的。 新的 lightweight-charts 通常可以获得性能改进和bug修复…...

React第二十七章(Suspense)

Suspense Suspense 是一种异步渲染机制&#xff0c;其核心理念是在组件加载或数据获取过程中&#xff0c;先展示一个占位符&#xff08;loading state&#xff09;&#xff0c;从而实现更自然流畅的用户界面更新体验。 应用场景 异步组件加载&#xff1a;通过代码分包实现组件…...

C# Dynamic关键字

一、引言&#xff1a;开启动态编程之门 在 C# 的编程世界里&#xff0c;长久以来我们习惯了静态类型语言带来的严谨与稳定。在传统的 C# 编程中&#xff0c;变量的类型在编译时就已经确定&#xff0c;这就像是给每个变量贴上了一个固定的标签&#xff0c;在整个代码执行过程中…...

大一计算机的自学总结:位运算的应用及位图

前言 不仅异或运算有很多骚操作&#xff0c;位运算本身也有很多骚操作。&#xff08;尤其后几个题&#xff0c;太逆天了&#xff09; 一、2 的幂 class Solution { public:bool isPowerOfTwo(int n) {return n>0&&n(n&-n);} }; 根据二进制表示数的原理&#…...

解决报错“The layer xxx has never been called and thus has no defined input shape”

解决报错“The layer xxx has never been called and thus has no defined input shape”(这里写自定义目录标题) 报错显示 最近在跑yolo的代码时遇到这样一个错误&#xff0c;显示“the layer {self.name} has never been called”.这个程序闲置了很久&#xff0c;每次一遇到…...

【AI论文】FilmAgent: 一个用于虚拟3D空间中端到端电影制作自动化的多智能体框架

摘要&#xff1a;虚拟电影制作涉及复杂的决策过程&#xff0c;包括剧本编写、虚拟摄影以及演员的精确定位和动作设计。受近期基于语言智能体社会的自动化决策领域进展的启发&#xff0c;本文提出了FilmAgent&#xff0c;这是一个新颖的、基于大型语言模型&#xff08;LLM&#…...

hive:数据导入,数据导出,加载数据到Hive,复制表结构

hive不建议用insert,因为Hive是建立在Hadoop之上的数据仓库工具&#xff0c;主要用于批处理和大数据分析&#xff0c;而不是为OLTP&#xff08;在线事务处理&#xff09;操作设计的。INSERT操作会非常慢 数据导入 命令行界面:建一个文件 查询数据>>复制>>粘贴到新…...

VUE之路由Props、replace、编程式路由导航、重定向

目录 1、路由_props的配置 2、路由_replaces属性 3、编程式路由导航 4、路由重定向 1、路由_props的配置 1&#xff09;第一种写法&#xff0c;将路由收到的所有params参数作为props传给路由组件 只能适用于params参数 // 创建一个路由器&#xff0c;并暴露出去// 第一步…...

虹科分享 | 汽车NVH小课堂之听音辨故障

随着车主开始关注汽车抖动异响问题&#xff0c;如何根据故障现象快速诊断异响来源&#xff0c;成了汽修人的必修课。 一个比较常用的方法就是靠“听”——“听音辨故障”。那今天&#xff0c;虹科Pico也整理了几个不同类型的异响声音&#xff0c;一起来听听看你能答对几个吧 汽…...

Transfoemr的解码器(Decoder)与分词技术

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;解码器&#xff08;Decoder&#xff09;和分词技术是两个至关重要的概念。解码器是序列生成任务的核心组件&#xff0c;而分词则是将文本数据转换为可处理形式的基础步骤。 一、解码器&#xff08;Decoder&…...

Django-Admin WebView 集成项目技术规范文档 v2.1

Django-Admin WebView 集成项目技术规范文档 v2.1 系统架构规范 1.1 技术栈要求 前端框架:Flutter: 3.27.1 (空安全版本)Dart: 3.3.1 (支持元编程)webview_flutter: ^4.10.0 (带Hybrid Composition支持)后端要求:Django: 4.2.x LTS (安全支持至2026)Python: 3.11.x (启用PEP …...

【开源免费】基于Vue和SpringBoot的社区智慧养老监护管理平台(附论文)

本文项目编号 T 163 &#xff0c;文末自助获取源码 \color{red}{T163&#xff0c;文末自助获取源码} T163&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

作業系統:設計與實現-母本

2023 南京大學《作業系統:設計與實現》 課程主頁(含講義):https://jyywiki.cn/OS/2023/ 【Python 实现操作系统模型 [南京大学2023操作系统-P4] (蒋炎岩)-哔哩哔哩】 https://b23.tv/jakxDbh 用Python实现操作系统模型讲义 一、操作系统基础概念 1.1 定义 操作系统(Oper…...

excel如何查找一个表的数据在另外一个表是否存在

比如“Sheet1”有“张三”、“李四”“王五”三个人的数据&#xff0c;“Sheet2”只有“张三”、“李四”的数据。我们通过修改“Sheet1”的“民族”或者其他空的列&#xff0c;修改为“Sheet2”的某一列。这样修改后筛选这个修改的列为空的或者为出错的&#xff0c;就能找到两…...

当AI学会“顿悟”:DeepSeek-R1如何用强化学习突破推理边界?

开篇&#xff1a;一场AI的“青春期叛逆” 你有没有想过&#xff0c;AI模型在学会“推理”之前&#xff0c;可能也经历过一段“中二时期”&#xff1f;比如&#xff0c;解题时乱写一通、语言混搭、答案藏在火星文里……最近&#xff0c;一支名为DeepSeek-AI的团队&#xff0c;就…...