Qt C++设计模式->享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享相同对象来减少内存使用,尤其适合在大量重复对象的情况下。它通过将对象的可共享部分抽取出来,并在多个上下文中共享,从而避免对象的多次创建。

享元模式的应用场景

享元模式常用于减少内存开销,特别是在系统中存在大量细粒度对象时。例如,在图形界面中,大量按钮、图标等UI组件可能具有相同的外观,只需要少量的内部状态不同,这时候可以用享元模式共享相同的外观。其他应用场景包括字符处理系统、游戏中的对象管理(如子弹、树木等重复的对象),以及数据库连接池等。

享元模式的核心思想

享元模式将对象的状态分为两类:

  • 内在状态:可以共享的、不随外部环境变化的状态。

  • 外在状态:不可以共享的、随外部环境变化的状态,由客户端传入。

通过将内在状态共享,并由外部提供外在状态,享元模式大大减少了内存的占用。

享元模式示例代码

假设你正在开发一款绘图软件,需要在屏幕上绘制大量形状,如圆形。每个圆形有相同的颜色和大小,但它们的位置不同。使用享元模式可以减少内存开销,因为我们可以共享相同的圆形对象,只改变它们的位置。

#include <QDebug>
#include <QString>
#include <QHash>// 享元类:表示共享的圆形对象
class Circle {
private:QString color;  // 内在状态(可以共享的部分)int radius;     // 内在状态(可以共享的部分)public:Circle(const QString& color, int radius) : color(color), radius(radius) {}void draw(int x, int y) const {qDebug() << "Drawing circle with color" << color << "radius" << radius << "at position" << x << "," << y;}
};// 享元工厂:用于管理和提供享元对象
class CircleFactory {
private:QHash<QString, Circle*> circleMap;  // 存储已创建的享元对象public:Circle* getCircle(const QString& color, int radius) {QString key = color + QString::number(radius);// 如果共享对象已存在,则返回它if (circleMap.contains(key)) {return circleMap[key];}// 否则创建新的享元对象并存储起来Circle* newCircle = new Circle(color, radius);circleMap.insert(key, newCircle);return newCircle;}~CircleFactory() {// 清理内存for (auto circle : circleMap) {delete circle;}}
};// 使用示例
int main() {CircleFactory* factory = new CircleFactory();// 获取共享的圆形对象,并在不同位置绘制Circle* redCircle = factory->getCircle("Red", 10);redCircle->draw(10, 20);Circle* redCircle2 = factory->getCircle("Red", 10);  // 获取相同颜色和半径的圆形,应该复用上面的对象redCircle2->draw(30, 40);Circle* blueCircle = factory->getCircle("Blue", 15);blueCircle->draw(50, 60);// 清理内存delete factory;return 0;
}

代码解析

  • Circle类:享元类,表示可以共享的圆形对象。它包含内在状态(颜色和半径),这些状态可以在多个圆形对象中共享。

  • CircleFactory类:享元工厂,负责管理和提供共享的圆形对象。它通过一个哈希表(circleMap)来存储已经创建的享元对象。如果请求的对象已经存在,直接返回它;否则创建新的对象并存储起来。

  • 客户端代码:客户端通过CircleFactory获取享元对象,并为不同的外在状态(位置)进行绘制。相同的圆形对象只会创建一次。

享元模式的优点

  • 节省内存:享元模式通过共享相同的对象,减少了系统中重复对象的数量,从而降低了内存使用。

  • 提高性能:通过减少对象的创建,享元模式可以提高系统的运行效率,特别是在大量重复对象的情况下。

享元模式的缺点

  • 增加复杂性:享元模式要求将对象的内在状态和外在状态分离,这会增加系统的设计复杂性,尤其是在无法明确区分这两者时。

  • 管理外在状态:外在状态由客户端负责传递,因此客户端必须正确管理这些状态,否则容易导致混乱。

适合使用享元模式的情况

  • 大量细粒度对象的场景:如果系统中需要创建大量对象,且这些对象存在相同的状态,享元模式可以帮助减少内存使用。

  • 对象的大部分状态可以共享:当对象的多数属性可以在多个实例间共享时,可以使用享元模式来优化性能。

  • 性能瓶颈集中在内存占用:如果系统因为大量对象的创建导致内存消耗过高,享元模式是很好的解决方案。

享元模式与其他模式的区别

  • 与单例模式的区别:单例模式确保某个类只有一个实例,而享元模式则通过共享对象来减少内存占用,它可以创建多个实例,但这些实例具有相同的内在状态。

  • 与原型模式的区别:原型模式通过复制已有的对象来生成新对象,而享元模式则通过共享现有的对象来减少对象的数量。

Qt中的享元模式应用

在Qt开发中,享元模式可以用于共享大量的UI组件、图形对象或资源。例如,许多图标在不同地方使用相同的图形,可以通过享元模式来减少内存使用。此外,Qt中的字体管理、样式表等机制也可以借鉴享元模式的思想,避免重复加载相同的资源。

享元模式在优化系统性能和减少内存使用方面非常有效,特别是在需要创建大量细粒度对象的场景中。

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

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

相关文章

Tomcat为什么要打破双亲委派?怎么保证安全

Tomcat打破双亲委派模型的原因主要是为了解决Web应用程序中的类加载冲突问题&#xff0c;并提供更好的灵活性和可扩展性。在Java中&#xff0c;双亲委派模型是一种类加载机制&#xff0c;它确保了类加载的安全性和一致性&#xff0c;但在Web应用程序的场景下&#xff0c;它可能…

MySQL和Doris开窗函数LAG执行时的区别

目标表的表结构 CREATE TABLE point_value_status_color_tmp ( id bigint NOT NULL, org_id varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, device_id varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, origin_ti…

数据库课程设计案例:在线教育管理系统

一、项目背景 随着在线教育的兴起&#xff0c;传统的教学管理模式面临着新的挑战。在线教育管理系统旨在为学生、教师和管理员提供一个高效、便捷的学习与管理平台&#xff0c;以提升学习效果和管理效率。 二、系统功能需求 用户管理 用户注册与登录角色管理&#xff08;学生…

CSS面试真题 part1

CSS面试真题 part1 1、说说你对盒子模型的理解2、谈谈你对BFC的理解3、什么是响应式设计&#xff1f;响应式设计的基本原理是什么&#xff1f;如何做&#xff1f;4、元素水平垂直居中的方法有哪些&#xff1f;如果元素不定宽高呢&#xff1f;5、如何实现两栏布局&#xff0c;右…

目标检测——VOC2007数据集

目标检测入门code 文件目录 下载数据集——在官网下载VOC2007数据集 下载训练数据集 TRAIN data 下载测试数据集 TEST data 解压数据集 解压——训练数据集&#xff0c;在服务器上&#xff0c;目录为VOCdevkit 部分文件目录 全部文件总目录 解压——测试数据集 &#xff08;…

Unity 与虚幻引擎对比:两大游戏开发引擎的优劣分析

在游戏开发领域&#xff0c;Unity 和虚幻引擎&#xff08;Unreal Engine&#xff09;是两款最为知名且广泛使用的引擎。它们各有特点&#xff0c;适合不同类型的开发者和项目。在这篇博客中&#xff0c;我们将深入探讨这两大引擎的核心功能、适用场景、优缺点&#xff0c;以及如…

DMDSC更换DCR和VOTE磁盘

DMDSC更换DCR和VOTE磁盘 为了提高DMDSC集群运行速度和节点之间通信协调的效率&#xff0c;需要将运行在机械盘上的dcr和vote磁盘替换到SSD高效磁盘上。将原来200M的dcr和vote机械磁盘&#xff0c;换成500M的SSD高效磁盘。 磁盘替换规划信息如下所示&#xff1a; 信息说明 替…

什么是IPv6

目前国内的网络正在快速的向IPv6升级中&#xff0c;从网络基础设施如运营商骨干网、城域网&#xff0c;到互联网服务商如各类云服务&#xff0c;以及各类终端设备厂商如手机、电脑、路由器、交换机等。目前运营商提供的IPv6线路主要分为支持前缀授权和不支持前缀授权两种。 说…

Python酷玩之旅_如何连接MySQL(mysql-connector-python)

前言 Python作为数据科学、机器学习等领域的必选武器&#xff0c;备受各界人士的喜爱。当你面对不同类型、存储于各类介质的数据时&#xff0c;第一时间是不是要让它亮个相&#xff1f;做个统计&#xff0c;画个图表&#xff0c;搞个报表… 等等。 正如Java中的JdbcDriver一样…

真正的Open AI ——LLaMA颠覆开源大模型

1. LLaMA 简介 LLaMA&#xff08;Large Language Model Meta AI&#xff09;是由Meta&#xff08;原Facebook&#xff09;推出的一个大型语言模型系列&#xff0c;旨在通过更小的模型规模和更少的计算资源&#xff0c;实现与其他主流语言模型&#xff08;如GPT&#xff09;相媲…

【解密 Kotlin 扩展函数】扩展属性与扩展函数类似(十九)

导读大纲 1.1.1 扩展属性的创建和使用 1.1.1 扩展属性的创建和使用 之前, 我们已经了解声明 Kotlin 属性的语法 Kotlin中的顶级属性–传送门就像扩展函数一样,我们也可以指定扩展属性就像之前所说&#xff0c;属性和函数的区别在于前者是特征&#xff0c;后者是行为 相比扩展函…

【漏洞复现】金和OA C6 GeneralXmlhttpPage.aspx Sql注入漏洞

免责声明: 本文旨在提供有关特定漏洞的信息,以帮助用户了解潜在风险。发布此信息旨在促进网络安全意识和技术进步,并非出于恶意。读者应理解,利用本文提到的漏洞或进行相关测试可能违反法律或服务协议。未经授权访问系统、网络或应用程序可能导致法律责任或严重后果…

编程思维之函数返回函数

当我们有一个函数1他需要封装成公共函数&#xff0c;但是了他需要传入一个组件内的值1才能进行逻辑&#xff0c;而我们在使用她的时候又不想传入两个参数&#xff0c;可以把函数1封装成返回函数2的一个函数&#xff0c;函数1需要传入值1在决定函数2. 然后在组件内得到函数2&…

《后端程序猿 · Spring事务失效场景》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

git commit -am 仅提交已修改文件

git commit -am 是一个 Git 命令&#xff0c;用于将所有已跟踪&#xff08;tracked&#xff09;文件的修改添加到暂存区&#xff0c;并同时创建一个新的提交。 具体解释&#xff1a; -a&#xff1a;表示自动暂存所有已跟踪的文件的修改&#xff08;包括修改和删除&#xff09…

2024/9/29周报

文章目录 摘要Abstract污水处理工艺流程整体介绍粗格栅细格栅曝气沉砂池提升泵房峰谷平策略 初沉池&#xff08;一级处理&#xff09;工作原理运行管理 氧化沟生化池&#xff08;二级处理&#xff09;二沉池工作原理运行参数 高效沉淀池功能与特点工作原理 深度处理&#xff08…

LeetCode 918. 环形子数组的最大和

原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给定一个长度为 n 的环形整数数组 nums &#xff0c;返回 nums 的非空 子数组 的最大可能和 。 环形数组 意味着数组的末端将会与开头相连呈环状。形式上&#xff0c; nums[i] 的下一个元素是 nums[(i 1) % n…

防止错误输入!Excel单元格限制输入内容的三种有效方式

在Excel中&#xff0c;限制单元格输入内容可以帮助避免数据输入错误&#xff0c;确保数据的一致性和准确性。今天小编分享三种方法&#xff0c;可以轻松限制Excel单元格的输入内容&#xff0c;确保数据输入符合预期要求&#xff0c;一起来看看吧&#xff01; 方法一&#xff1a…

Register Two Point Sets 注册两个点集

文章目录 Register Two Point Sets 注册两个点集Visualize Gradient Descent 可视化梯度下降Hyperparameter Search 超参数搜索JensenHavrdaCharvatTsallisPointSetToPointSetMetricv4类说明 原文url: https://examples.itk.org/src/registration/metricsv4/registertwopointse…

【AI驱动TDSQL-C Serverless数据库技术实战】 AI电商数据分析系统——探索Text2SQL下AI驱动代码进行实际业务

目录 一、Text2SQL简介二、基于TDSQL-C Serverless的Text2SQL实战2.1、程序流程图2.2、实践流程2.2.1、配置TDSQL-C2.2.2、部署LLAMA模型2.2.3、本地依赖安装2.2.4、应用构建 2.3、运行效果 三、Text2SQL下的AI驱动 Text2SQL 是一种将自然语言查询转换为 SQL 查询的技术&#x…