新闻中心

c++如何实现一个享元设计模式_c++ Flyweight模式节约内存

2025-12-02
浏览次数:
返回列表
享元模式通过共享内部状态减少内存使用,如示例中多棵树共享相同TreeType实例,仅外部位置不同,从而在大量相似对象场景下显著降低内存开销。

c++如何实现一个享元设计模式_c++ flyweight模式节约内存

在C++中,享元(Flyweight)模式是一种用于减少内存使用的设计模式,特别适用于大量相似对象的场景。它的核心思想是共享尽可能多的相同数据,把不变的部分提取为“内部状态”,而将变化的部分作为“外部状态”传入,避免重复创建对象。

享元模式的核心结构

享元模式通常包含以下几个部分:

  • Flyweight(抽象享元类):定义接口,描述操作外部状态的方法。
  • ConcreteFlyweight(具体享元类):实现Flyweight接口,并存储内部状态(可共享)。
  • UnsharedConcreteFlyweight(非共享具体享元):某些情况下不需要共享的对象,可选。
  • FlyweightFactory(享元工厂):负责管理享元对象,通过键值缓存已创建的实例,避免重复创建。

一个实际的C++实现示例

假设我们要绘制森林中的树,每棵树有种类(type)、颜色、高度等属性。其中“种类”和“颜色”是固定的,可以共享;而“位置(x, y)”是变化的,应作为外部状态传入。

#include <iostream>
#include <string>
#include <map>
#include <memory>
<p>// 抽象享元类
class TreeType {
public:
std::string type;
std::string color;</p><pre class='brush:php;toolbar:false;'>TreeType(const std::string& t, const std::string& c) : type(t), color(c) {}

void draw(int x, int y) const {
    std::cout << "Drawing " << color << " " << type 
              << " at (" << x << ", " << y << ")\n";
}

};

魔术橡皮擦 魔术橡皮擦

智能擦除、填补背景内容

魔术橡皮擦 80 查看详情 魔术橡皮擦

// 享元工厂 class TreeFactory { private: static std::map<:string std::shared_ptr>> pool;

// 生成唯一键
static std::string getKey(const std::string& type, const std::string& color) {
    return type + "_" + color;
}

public: static std::shared_ptr getTreeType(const std::string& type, const std::string& color) { std::string key = getKey(type, color); if (pool.find(key) == pool.end()) { pool[key] = std::make_shared(type, color); std::cout

// 静态成员初始化 std::map<:string std::shared_ptr>> TreeFactory::pool;

// 外层封装类:代表一棵树 class Tree { private: int x, y; std::shared_ptr type;

public: Tree(int x, int y, const std::shared_ptr& type) : x(x), y(y), type(type) {}

void draw() const {
    type->draw(x, y);
}

};

// 森林类,包含多棵树 class Forest { private: std::vector trees;

public: void plantTree(int x, int y, const std::string& type, const std::string& color) { auto treeType = TreeFactory::getTreeType(type, color); trees.emplace_back(x, y, treeType); }

void draw() const {
    for (const auto& tree : trees) {
        tree.draw();
    }
}

};

使用示例:

int main() {
    Forest forest;
    forest.plantTree(1, 2, "Oak", "Green");
    forest.plantTree(3, 4, "Oak", "Green");  // 共享同一个 TreeType
    forest.plantTree(5, 6, "Pine", "DarkGreen");
<pre class='brush:php;toolbar:false;'>forest.draw();

return 0;

}

为什么能节约内存?

在这个例子中,即使我们创建了上百棵“Oak - Green”类型的树,也只会有一个 TreeType 实例被创建并共享。所有树对象共用这个实例,只保存自己的位置信息。这样大大减少了内存开销,尤其适合大规模相似对象的场景,比如图形系统、文本编辑器中的字符格式、游戏中的粒子效果等。

注意事项与适用场景

  • 享元适合对象数量巨大且内部状态高度重复的情况。
  • 外部状态必须由客户端传入,不能放在享元对象内部。
  • 线程安全需额外处理,若多线程访问享元工厂,应加锁保护缓存map。
  • 过度使用可能增加代码复杂度,应权衡是否真的需要节省内存。

基本上就这些。通过共享不变状态,Flyweight模式有效降低了内存占用,是性能优化中的实用技巧之一。不复杂但容易忽略。

以上就是c++++如何实现一个享元设计模式_c++ Flyweight模式节约内存的详细内容,更多请关注其它相关文章!


# c++  # ai  # 如何实现  # red  # 为什么  # 内存占用  # stream  # win  # ios  # seo企业排名  # 商丘市专业网站优化推广seo多少钱  # 全网营销推广的效果如何  # 江苏培训网站建设  # 怀化运营网站建设优势  # 黄山批量关键词排名  # seo学习工具  # 天元区抖音营销推广招聘  # 银川网站建设与推广招聘  # 精准数字推广营销  # 数独  # 在这个  # 放在  # 是一种  # 几个  # 自己的  # 如何用  # 棵树  # 多线程 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 在Go Martini框架中高效服务动态生成图像的实践指南  神庙逃亡小游戏在线玩 神庙逃亡小游戏入口  163邮箱注册官网 免费申请163个人邮箱  在J*a中如何捕获IndexOutOfBoundsException_索引越界异常防护方法说明  如何解决电商平台定制报价请求的“黑洞”问题,SprykerQuoteRequest模块助你提升客户体验与销售效率  CKEditor 5 自定义构建在React应用中渲染失败的调试与解决  Win10如何清理注册表垃圾 Win10手动清理无效注册表【技巧】  解决 Vaadin 8 中大文件音频播放与定位时出现的 IOException  PyTorch模型训练效果不佳?深入剖析常见错误与调试技巧  mc.js免安装版 mc.js一键畅玩入口  Shopware订单对象中获取产品自定义字段的正确方法  Win11怎么开启卓越性能模式 Win11电源选项启用高性能释放硬件潜力【方法】  顺丰快递查单号物流信息 顺丰快递小程序查询入口  J*a中实现Go语言select通道多路复用机制  漫蛙漫画登录站点 漫蛙2正版漫画快速访问  yy漫画网页版官方入口_yy漫画官网登录页面链接  如何在J*a中使用Locale处理多语言环境  C++ vector二维数组定义_C++ vector of vector用法  蛙漫安全无毒 官方认证的绿色入口  PDO预处理语句中冒号的正确处理:区分SQL函数格式与命名占位符  EMS快递官网app_中国邮政速递物流手机客户端  Python实现多节点属性重叠度分析教程  谷歌推RCS信息存档功能:公司可监控员工私密信息!  手机屏幕碎了但能正常使用怎么办 手机外屏碎裂的修复建议  Win11怎么查看显卡显存 Win11显示适配器属性及专用视频内存查询  QQ邮箱官方网页版登录 QQ邮箱个人邮箱快速访问  AngularJS $http POST请求数据传递与Go后端接收实践  圆通快递查询实时追踪 圆通物流包裹状态快速查看  Spyder启动失败:字体文件权限拒绝错误解决方案  实现分段式页面滚动导航:CSS与J*aScript教程  C++如何进行游戏物理模拟_使用Box2D库为C++游戏添加2D物理效果  Golang指针如何与map组合使用_Golang map指针组合实践  精准捕获:如何在页面中监听除特定元素外的所有点击事件  火锅吃太多会怎样 火锅吃太多会上火吗  MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具  AO3镜像入口大全 AO3网页版内容访问全集  淘宝网网页版登录入口 淘宝官方网页版快捷登录  铁路12306改签能改到更早的车次吗_铁路12306改签提前车次规则  J*aScript中赋值与自增运算符的复杂交互与执行机制  sublime怎么预览Markdown渲染效果_Markdown Preview插件 for sublime教程  C++如何比较两个字符串_C++ string compare函数与操作符对比  c++如何实现一个简单的软件渲染器_c++从零开始的3D图形学  汽车之家官方网站官网入口_汽车之家网页版直接进入  必由学登录入口 必由学官方网站在线访问链接  如何在网页中实现特定地点的随机图片展示  Excel中VLOOKUP的第四个参数是干什么用的_Excel VLOOKUP第四参数作用解析  J*aScript异步迭代器_j*ascript异步遍历  html两个JS只运行一个怎么办_让双JS在html中都运行方法【技巧】  Lar*el表单中优雅地处理“返回”按钮以规避验证:最佳实践指南  msn官网入口地址手机版 msn官方网站手机最新链接 

搜索