首页 > 后端开发 > C++ > 正文

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

裘德小鎮的故事
发布: 2025-12-02 09:46:02
原创
183人浏览过
享元模式通过共享内部状态减少内存使用,如示例中多棵树共享相同TreeType实例,仅外部位置不同,从而在大量相似对象场景下显著降低内存开销。

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

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

享元模式的核心结构

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

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

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

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

立即学习C++免费学习笔记(深入)”;

#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";
}
登录后复制

};

ImagetoCartoon
ImagetoCartoon

一款在线AI漫画家,可以将人脸转换成卡通或动漫风格的图像。

ImagetoCartoon 106
查看详情 ImagetoCartoon

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

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

public: static std::shared_ptr<TreeType> 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<TreeType>(type, color); std::cout << "Created new TreeType: " << key << "\n"; } return pool[key]; } };

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

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

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

void draw() const {
    type->draw(x, y);
}
登录后复制

};

// 森林类,包含多棵树 class Forest { private: std::vector<Tree> 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模式节约内存的详细内容,更多请关注php中文网其它相关文章!

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号