c++如何实现一个享元模式_c++结构型设计模式Flyweight【性能优化】

享元模式通过共享内在状态、分离外在状态来减少内存占用;核心是用工厂缓存并复用相同内在状态的对象,客户端传入外在状态调用行为。

c++如何实现一个享元模式_c++结构型设计模式flyweight【性能优化】

享元模式(Flyweight)在 C++ 中主要用于减少内存占用,通过共享大量细粒度对象来提升性能,特别适用于对象数量庞大、状态可分“内在”与“外在”的场景(比如文字编辑器中的字符、游戏中的子弹、GUI 中的图标等)。

核心思想:分离内在状态与外在状态

内在状态(Intrinsic State)是共享的、不可变的,属于享元对象自身,比如字符的字体、大小、颜色(若统一);
外在状态(Extrinsic State)是不共享的、变化的,由客户端维护并传入,比如字符在文档中的位置、行号、是否选中等。

关键不是“把对象变少”,而是“避免重复创建相同内在状态的对象”。

手动实现享元工厂(推荐初学理解)

std::mapstd::unordered_map 缓存已创建的享元实例,按内在状态作 key 查找复用:

定义享元基类(接口或抽象类),声明操作函数,参数接收外在状态 派生具体享元类,只保存内在状态(const 成员),实现逻辑 实现享元工厂类,负责创建/获取享元,内部用 map 管理生命周期(注意线程安全需加锁) 客户端不再 new 具体类,而是调用工厂 getFlyweight(intrinsicKey),再传 extrinsic 参数调用其方法

示例关键片段:

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

class CharacterFlyweight {public:    virtual void render(int x, int y) const = 0; // 外在状态:坐标    virtual ~CharacterFlyweight() = default;};class ConcreteChar : public CharacterFlyweight {    const char ch_;    const std::string font_;    const int size_;public:    ConcreteChar(char c, std::string f, int s)         : ch_(c), font_(std::move(f)), size_(s) {}        void render(int x, int y) const override {        std::cout << "Draw '" << ch_ << "' at (" << x << "," << y << ") "                  << "with " << font_ << " " << size_ << "ptn";    }};class FlyweightFactory {    std::unordered_map<std::string, std::unique_ptr> pool;public:    CharacterFlyweight& getFlyweight(const std::string& key) {        auto it = pool.find(key);        if (it != pool.end()) return *it->second;                // 解析 key(如 "A|Arial|12")→ 构造对象        auto pos1 = key.find('|'), pos2 = key.find('|', pos1+1);        char c = key[0];        std::string font = key.substr(pos1+1, pos2-pos1-1);        int size = std::stoi(key.substr(pos2+1));                pool[key] = std::make_unique(c, font, size);        return *pool[key];    }};

使用智能指针 + 工厂封装(更现代、安全)

避免裸指针和手动管理,用 std::shared_ptr 管理享元生命周期,工厂返回 const 引用或 shared_ptr:

享元类建议设计为轻量、无状态修改(所有成员 const 或 immutable) 工厂内部用 static 局部变量 + unordered_map 实现单例式缓存,天然线程安全(C++11 起) 客户端拿到的是共享指针,无需关心释放;也可返回 const CharacterFlyweight& 提高性能(但需确保工厂生命周期长于使用者)

什么时候不该用享元?

享元不是银弹,滥用反而降低可读性和性能:

对象总数很少( 内在状态组合爆炸(比如 10 种字体 × 5 种大小 × 20 种颜色 → 1000 种 key),缓存反而吃内存 外在状态传递复杂,导致接口臃肿、调用频繁出错 对象本身已很轻量(如仅含一个 int),共享意义不大

基本上就这些。享元本质是空间换时间 + 状态解耦,C++ 实现关键在于明确区分内外状态、合理设计 key、用好容器和智能指针。不复杂但容易忽略外在状态的归属和线程安全性。

以上就是c++++如何实现一个享元模式_c++结构型设计模式Flyweight【性能优化】的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1488699.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 11:46:40
下一篇 2025年12月19日 11:46:54

相关推荐

发表回复

登录后才能评论
关注微信