全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

c++如何实现享元模式 c++设计模式之Flyweight【实例】

享元模式通过共享内部状态、分离外部状态来减少内存占用。C++中以字符渲染为例,定义享元接口和具体类,工厂用map缓存实例,客户端通过工厂获取并传入外部状态调用display。

享元模式(Flyweight)在 C++ 中主要用于减少内存占用,通过共享大量细粒度对象来避免创建过多重复实例。它的核心是将对象状态分为 内部状态(可共享、不可变)和 外部状态(不可共享、由客户端维护)。下面用一个典型场景——文字编辑器中字符渲染——来演示如何用 C++ 实现享元模式。

享元接口与具体享元类

定义统一接口,让所有享元对象对外提供一致的使用方式。内部状态(如字体、字号、颜色)在构造时固定,不随上下文变化:

class CharacterFlyweight {
public:
    virtual ~CharacterFlyweight() = default;
    virtual void display(char c, int x, int y) const = 0; // 外部状态:位置、具体字符
};

class ConcreteCharacter : public CharacterFlyweight { private: const char m_font; const int m_size; const std::string m_color;

public: ConcreteCharacter(char font, int size, const std::string& color) : m_font(font), m_size(size), m_color(color) {}

void display(char c, int x, int y) const override {
    std::cout << "Char '" << c 
              << "' at (" << x << "," << y << ") "
              << "with font " << m_font 
              << ", size " << m_size 
              << ", color " << m_color << "\n";
}

};

享元工厂:管理共享对象池

工厂负责按需创建或复用享元对象。用 std::mapstd::unordered_map 缓存已创建的实例,键通常由内部状态组合构成:

class CharacterFactory {
private:
    std::map, std::unique_ptr> m_pool;

public: CharacterFlyweight* getCharacter(char font, int size, const std::string& color) { auto key = std::make_tuple(font, size, color); if (m_pool.find(key) == m_pool.end()) { m_pool[key] = std::make_unique(font, size, color); } return m_pool[key].get(); } };

客户端代码:使用享元而非直接 new

客户端不再自行构造享元,而是向工厂请求;每次调用 display() 传入外部状态(坐标、实际字符),实现“一份享元,多次显示”:

int main() {
    CharacterFactory factory;
// 获取两个相同样式的享元(实际只创建一次)
CharacterFlyweight* bold12red = factory.getCharacter('B', 12, "red");
CharacterFlyweight* bold12red2 = factory.getCharacter('B', 12, "red"); // 复用

// 不同样式会创建新实例
CharacterFlyweight* italic10blue = factory.getCharacter('I', 10, "blue");

// 渲染不同位置的相同样式字符
bold12red->display('H', 0, 0);
bold12red2->display('e', 1, 0);
italic10blue->display('l', 2, 0);

return 0;

}

关键注意事项

  • 内部状态必须是 不可变的(建议用 const 成员),否则共享会导致逻辑错误
  • 享元对象应是 无状态的或仅依赖传入的外部参数,不能持有上下文相关数据
  • 工厂类可加线程安全封装(如加锁),适用于多线程环境
  • 若享元数量极少或生命周期极短,引入享元反而增加复杂度,需权衡

这个例子展示了享元模式如何在 C++ 中落地:用工厂控制创建、用接口解耦使用、靠内部/外部状态分离实现高效复用。不复杂但容易忽略细节。


# ai  # c++  # 内存占用  # red  # 封装  # const  # 接口  # 线程  # 多线程  # map  # 对象  # display  # 客户端  # 复用  # 适用于  # 为例  # 而非  # 应是  # 主要用于  # 极少  # 中以 


相关文章: 建站之星后台搭建步骤解析:模板选择与产品管理实操指南  网站制作知乎推荐,想做自己的网站用什么工具比较好?  网站制作网站,深圳做网站哪家比较好?  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  如何通过虚拟主机快速搭建个人网站?  如何高效利用200m空间完成建站?  Android自定义控件实现温度旋转按钮效果  如何快速搭建安全的FTP站点?  如何在宝塔面板中修改默认建站目录?  如何快速配置高效服务器建站软件?  建站之星IIS配置教程:代码生成技巧与站点搭建指南  如何选择可靠的免备案建站服务器?  网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  建站之星如何一键生成手机站?  内网网站制作软件,内网的网站如何发布到外网?  建站之星代理费用多少?最新价格详情介绍  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  如何在阿里云虚拟服务器快速搭建网站?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  江苏网站制作公司有哪些,江苏书法考级官方网站?  建站之星如何保障用户数据免受黑客入侵?  青岛网站设计制作公司,查询青岛招聘信息的网站有哪些?  ,想在网上投简历,哪几个网站比较好?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  北京建设网站制作公司,北京古代建筑博物馆预约官网?  想学网站制作怎么学,建立一个网站要花费多少?  如何通过建站之星自助学习解决操作问题?  北京网站制作的公司有哪些,北京白云观官方网站?  如何快速搭建个人网站并优化SEO?  c# 在ASP.NET Core中管理和取消后台任务  行程制作网站有哪些,第三方机票电子行程单怎么开?  制作企业网站建设方案,怎样建设一个公司网站?  网站制作话术技巧,网站推广做的好怎么话术?  表情包在线制作网站免费,表情包怎么弄?  零服务器AI建站解决方案:快速部署与云端平台低成本实践  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  建站主机是否等同于虚拟主机?  济南网站制作的价格,历城一职专官方网站?  如何获取免费开源的自助建站系统源码?  广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的?  如何在Tomcat中配置并部署网站项目?  如何实现建站之星域名转发设置?  黑客如何通过漏洞一步步攻陷网站服务器?  上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?  如何快速上传自定义模板至建站之星?  建站之星安装提示数据库无法连接如何解决?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。