模板泛化类如何卸载释放内存
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);} } 以上该怎么写删除对象操作,类如下: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模块的源码分析
一、背景 在主流的内存库里,jemalloc作为android 5.0-android 10.0的默认分配器肯定占用了非常重要的一席之地。jemalloc的低版本和高版本之间的差异特别大,低版本的诸多网上整理的总结,无论是在概念上和还是在结构体命名上在新版本中很多都…...
03-机器学习-数据获取
一、流行机器学习数据集 主流机器学习数据集汇总 数据集名称描述来源MNIST手写数字图像数据集,由美国人口普查局员工书写。MNIST官网ImageNet包含数百万张图像,用于图像分类和目标检测。ImageNet官网AudioSet包含YouTube音频片段,用于声音分…...
编程题-最长的回文子串(中等)
题目: 给你一个字符串 s,找到 s 中最长的回文子串。 示例 1: 输入:s "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。示例 2: 输入:s &…...
爱书爱考平台说明
最近我开发了一个综合性的考试平台,内容包括但不限于职业资格证考试、成人教育、国家公务员考试等内容。目前1.0版本已经开发完成,其他的功能陆续完善中。 微信小程序搜索"爱书爱考" 微信小程序图标如下图: 目前维护了java相关的面试题的考题…...
doris: MAP数据类型
MAP<K, V> 表示由K, V类型元素组成的 map,不能作为 key 列使用。 目前支持在 Duplicate,Unique 模型的表中使用。 K, V 支持的类型有: BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, FLOAT, DOUBLE, DECIMAL, DECIMALV3, DAT…...
JUC--ConcurrentHashMap底层原理
ConcurrentHashMap底层原理 ConcurrentHashMapJDK1.7底层结构线程安全底层具体实现 JDK1.8底层结构线程安全底层具体实现 总结JDK 1.7 和 JDK 1.8实现有什么不同?ConcurrentHashMap 中的 CAS 应用 ConcurrentHashMap ConcurrentHashMap 是一种线程安全的高效Map集合…...
Sklearn 中的逻辑回归
逻辑回归的数学模型 基本模型 逻辑回归主要用于处理二分类问题。二分类问题对于模型的输出包含 0 和 1,是一个不连续的值。分类问题的结果一般不能由线性函数求出。这里就需要一个特别的函数来求解,这里引入一个新的函数 Sigmoid 函数,也成…...
Spring Boot 自定义属性
Spring Boot 自定义属性 在 Spring Boot 应用程序中,application.yml 是一个常用的配置文件格式。它允许我们以层次化的方式组织配置信息,并且比传统的 .properties 文件更加直观。 本文将介绍如何在 Spring Boot 中读取和使用 application.yml 中的配…...
1.2第1章DC/DC变换器的动态建模-1.2Buck-Boost 变换器的交流模型--电力电子系统建模及控制 (徐德鸿)--读书笔记
1.2 Buck-Boost 变换器的交流模型 Buck- Boost变换器是一种典型的DC/DC变换器,具有升压和降压功能其输出电压的极性与输入电压相反,见图1-4a。当电感L的电流i(t)连续时一个开关周期可以分为两个阶段。在阶段1,开关在位置1时,即&am…...
数据结构:二叉树—面试题(一)
目录 1、相同的树 2、另一棵树的子树 3、翻转二叉树 4、平衡二叉树 5、对称二叉树 6、二叉树遍历 7、二叉树的分层遍历 1、相同的树 习题链接https://leetcode.cn/problems/same-tree/description/ 描述: 给你两棵二叉树的根节点 p 和 q ,编写一…...
DDD 和 TDD
领域驱动设计(DDD) DDD 是一种软件开发方法,强调通过与领域专家的密切合作来构建一个反映业务逻辑的模型。其核心思想是将业务逻辑和技术实现紧密结合,以便更好地解决复杂的业务问题。 DDD 的关键概念: 1. 领域模型 …...
LangChain概述
文章目录 为什么需要LangChainLLM应用开发的最后1公里LangChain的2个关键词LangChain的3个场景LangChain的6大模块 为什么需要LangChain 首先想象一个开发者在构建一个LLM应用时的常见场景。当你开始构建一个新项目时,你可能会遇到许多API接口、数据格式和工具。对于…...
Java基于SSM框架的互助学习平台小程序【附源码、文档】
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...
lightweight-charts-python 包 更新 lightweight-charts.js 的方法
lightweight-charts-python 是 lightweight-charts.js 的 python 包装,非常好用 lightweight-charts 更新比较频繁,导致 lightweight-charts-python 内置的 lightweight-charts 经常不是最新的。 新的 lightweight-charts 通常可以获得性能改进和bug修复…...
React第二十七章(Suspense)
Suspense Suspense 是一种异步渲染机制,其核心理念是在组件加载或数据获取过程中,先展示一个占位符(loading state),从而实现更自然流畅的用户界面更新体验。 应用场景 异步组件加载:通过代码分包实现组件…...
C# Dynamic关键字
一、引言:开启动态编程之门 在 C# 的编程世界里,长久以来我们习惯了静态类型语言带来的严谨与稳定。在传统的 C# 编程中,变量的类型在编译时就已经确定,这就像是给每个变量贴上了一个固定的标签,在整个代码执行过程中…...
大一计算机的自学总结:位运算的应用及位图
前言 不仅异或运算有很多骚操作,位运算本身也有很多骚操作。(尤其后几个题,太逆天了) 一、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的代码时遇到这样一个错误,显示“the layer {self.name} has never been called”.这个程序闲置了很久,每次一遇到…...
【AI论文】FilmAgent: 一个用于虚拟3D空间中端到端电影制作自动化的多智能体框架
摘要:虚拟电影制作涉及复杂的决策过程,包括剧本编写、虚拟摄影以及演员的精确定位和动作设计。受近期基于语言智能体社会的自动化决策领域进展的启发,本文提出了FilmAgent,这是一个新颖的、基于大型语言模型(LLM&#…...
hive:数据导入,数据导出,加载数据到Hive,复制表结构
hive不建议用insert,因为Hive是建立在Hadoop之上的数据仓库工具,主要用于批处理和大数据分析,而不是为OLTP(在线事务处理)操作设计的。INSERT操作会非常慢 数据导入 命令行界面:建一个文件 查询数据>>复制>>粘贴到新…...
VUE之路由Props、replace、编程式路由导航、重定向
目录 1、路由_props的配置 2、路由_replaces属性 3、编程式路由导航 4、路由重定向 1、路由_props的配置 1)第一种写法,将路由收到的所有params参数作为props传给路由组件 只能适用于params参数 // 创建一个路由器,并暴露出去// 第一步…...
虹科分享 | 汽车NVH小课堂之听音辨故障
随着车主开始关注汽车抖动异响问题,如何根据故障现象快速诊断异响来源,成了汽修人的必修课。 一个比较常用的方法就是靠“听”——“听音辨故障”。那今天,虹科Pico也整理了几个不同类型的异响声音,一起来听听看你能答对几个吧 汽…...
Transfoemr的解码器(Decoder)与分词技术
在自然语言处理(NLP)领域,解码器(Decoder)和分词技术是两个至关重要的概念。解码器是序列生成任务的核心组件,而分词则是将文本数据转换为可处理形式的基础步骤。 一、解码器(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 ,文末自助获取源码 \color{red}{T163,文末自助获取源码} T163,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程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”有“张三”、“李四”“王五”三个人的数据,“Sheet2”只有“张三”、“李四”的数据。我们通过修改“Sheet1”的“民族”或者其他空的列,修改为“Sheet2”的某一列。这样修改后筛选这个修改的列为空的或者为出错的,就能找到两…...
当AI学会“顿悟”:DeepSeek-R1如何用强化学习突破推理边界?
开篇:一场AI的“青春期叛逆” 你有没有想过,AI模型在学会“推理”之前,可能也经历过一段“中二时期”?比如,解题时乱写一通、语言混搭、答案藏在火星文里……最近,一支名为DeepSeek-AI的团队,就…...
