C++如何实现一个享元模式_C++设计模式之运用共享技术减少内存占用

发布时间 - 2025-12-30 00:00:00    点击率:
享元模式通过共享减少对象数量,C++中利用工厂和容器管理内部状态相同的对象,结合不可变设计与智能指针优化内存使用,适用于高频创建相似对象的场景。

享元模式(Flyweight Pattern)是一种结构型设计模式,它的核心思想是通过共享技术来支持大量细粒度对象的复用,从而减少内存中对象的数量,降低系统开销。在C++中,尤其适用于创建大量相似对象的场景,比如文本编辑器中的字符格式、游戏开发中的子弹或敌人类型等。

享元模式的核心概念

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

  • 内部状态(Intrinsic State):可以被共享,不会随环境改变,通常作为享元对象的成员变量。
  • 外部状态(Extrinsic State):依赖于上下文,不可共享,使用时由客户端传入。

通过分离这两类状态,多个上下文可以共享同一个享元对象,只需传入不同的外部状态即可表现出不同行为。

实现一个简单的享元工厂

在C++中,通常借助一个工厂类来管理享元对象的创建和共享。工厂维护一个已创建享元的容器(如map),避免重复创建相同内部状态的对象。

#include 
#include 
#include 

// 享元接口或基类 class CharacterStyle { public: CharacterStyle(const std::string& font, int size, const std::string& color) : font(font), size(size), color_(color) {}

void display(const std::string& content) const {
    std::cout zuojiankuohaophpcnzuojiankuohaophpcn "Text: " zuojiankuohaophpcnzuojiankuohaophpcn content 
              zuojiankuohaophpcnzuojiankuohaophpcn " | Font: " zuojiankuohaophpcnzuojiankuohaophpcn font_ 
              zuojiankuohaophpcnzuojiankuohaophpcn ", Size: " zuojiankuohaophpcnzuojiankuohaophpcn size_ 
              zuojiankuohaophpcnzuojiankuohaophpcn ", Color: " zuojiankuohaophpcnzuojiankuohaophpcn color_ zuojiankuohaophpcnzuojiankuohaophpcn std::endl;
}

private: std::string font; int size; std::string color_; };

// 享元工厂 class StyleFactory { public: CharacterStyle* getStyle(const std::string& font, int size, const std::string& color) { std::string key = font + "-" + std::to_string(size) + "-" + color;

    if (styles.find(key) == styles.end()) {
        styles[key] = new CharacterStyle(font, size, color);
    }
    return styles[key];
}

~StyleFactory() {
    for (auto& pair : styles) {
        delete pair.second;
    }
}

private: std::map<:string characterstyle> styles; };

上面代码中,CharacterStyle 表示字体样式,其内部状态是字体、大小和颜色。工厂通过组合这些属性生成唯一键,确保相同样式的对象只创建一次。

客户端使用示例

客户端通过工厂获取享元对象,并传入外部状态(如具体显示的文本内容)来使用。

int main() {
    StyleFactory factory;
// 模拟文档中有多个字符,但只有几种样式
CharacterStyle* style1 = factory.getStyle("Arial", 12, "black");
CharacterStyle* style2 = factory.getStyle("Times New Roman", 14, "red");
CharacterStyle* style3 = factory.getStyle("Arial", 12, "black"); // 应该复用 style1

style1-youjiankuohaophpcndisplay("Hello");
style2-youjiankuohaophpcndisplay("World");
style3-youjiankuohaophpcndisplay("!");

// 验证是否为同一对象
std::cout zuojiankuohaophpcnzuojiankuohaophpcn "style1 == style3: " zuojiankuohaophpcnzuojiankuohaophpcn (style1 == style3 ? "true" : "false") zuojiankuohaophpcnzuojiankuohaophpcn std::endl;

return 0;

}

输出结果会显示,尽管请求了两次相同的样式,但实际返回的是同一个对象指针,有效减少了内存占用。

注意事项与优化建议

  • 享元对象应设计为不可变(immutable),以保证共享安全。一旦创建,其内部状态不应被修改。
  • 工厂需管理对象生命周期,避免内存泄漏。可考虑使用智能指针(如std::shared_ptr)替代原始指针。
  • 键的生成要高效且无歧义,推荐使用字符串拼接或哈希方式。
  • 并非所有对象都适合做享元。仅当对象创建频繁、内部状态高度重复时才值得引入。

基本上就这些。享元模式通过共享减少对象数量,在C++中结合工厂和容器能有效控制内存使用,特别适合资源敏感的应用场景。关键在于合理划分内外状态,确保共享的安全与高效。


# c++  # ai  # ios  # stream  # 游戏开发  # 内存占用  # red  # String  # 成员变量  # const  # 字符串  # int  # 指针  # class  # public  # private  # map  # 对象  # 多个  # 适用于  # 客户端  # 两类  # 复用  # 的是  # 是一种  # 中有  # 只需  # 推荐使用 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  如何在香港免费服务器上快速搭建网站?  Laravel安装步骤详细教程_Laravel环境搭建指南  Android 常见的图片加载框架详细介绍  Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  奇安信“盘古石”团队突破 iOS 26.1 提权  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  Edge浏览器如何截图和滚动截图_微软Edge网页捕获功能使用教程【技巧】  零基础网站服务器架设实战:轻量应用与域名解析配置指南  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  Laravel如何生成API文档?(Swagger/OpenAPI教程)  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  深入理解Android中的xmlns:tools属性  中国移动官方网站首页入口 中国移动官网网页登录  油猴 教程,油猴搜脚本为什么会网页无法显示?  如何在云主机快速搭建网站站点?  如何快速搭建二级域名独立网站?  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  高防服务器:AI智能防御DDoS攻击与数据安全保障  Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  北京网站制作公司哪家好一点,北京租房网站有哪些?  详解阿里云nginx服务器多站点的配置  中山网站推广排名,中山信息港登录入口?  实例解析Array和String方法  详解Android——蓝牙技术 带你实现终端间数据传输  如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  Laravel怎么在Blade中安全地输出原始HTML内容  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  太平洋网站制作公司,网络用语太平洋是什么意思?  Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  Android使用GridView实现日历的简单功能  用v-html解决Vue.js渲染中html标签不被解析的问题  如何注册花生壳免费域名并搭建个人网站?  HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  如何快速生成可下载的建站源码工具?  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  Laravel如何实现本地化和多语言支持?(i18n教程)  node.js报错:Cannot find module &#39;ejs&#39;的解决办法  Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率