0

0

C++怎么实现一个享元模式_C++运用共享技术有效支持大量细粒度对象的模式

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-11-25 14:25:02

|

443人浏览过

|

来源于php中文网

原创

享元模式通过共享内部状态减少内存开销,适用于大量相似对象场景。C++中以工厂管理可共享的内部状态(如样式),结合智能指针避免重复创建,外部状态(如内容)由客户端传入,实现高效复用与低内存消耗。

c++怎么实现一个享元模式_c++运用共享技术有效支持大量细粒度对象的模式

享元模式(Flyweight Pattern)是一种结构型设计模式,主要用于减少创建大量相似对象时的内存开销。它通过共享已有的对象来避免重复创建,特别适用于系统中存在大量细粒度、相似对象的场景,比如文本编辑器中的字符格式、图形系统中的图元样式等。

C++ 实现享元模式的核心思路是:将对象中可共享的“内部状态”与不可共享的“外部状态”分离。内部状态存储在享元对象中,被多个上下文共享;外部状态则由客户端传入,不保存在享元内部。

享元模式的基本结构

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

  • Flyweight(抽象享元类):定义享元接口,声明接受外部状态的方法。
  • ConcreteFlyweight(具体享元类):实现 Flyweight 接口,并存储内部状态(可共享)。
  • UnsharedConcreteFlyweight(非共享享元类,可选):某些情况下不需要共享的对象。
  • FlyweightFactory(享元工厂):负责管理享元对象,确保相同内部状态的对象只创建一次。

一个简单的 C++ 实现示例

假设我们要实现一个文本编辑器,每个字符都有字体、颜色等属性。如果每个字符都独立保存这些信息,内存消耗巨大。使用享元模式,我们可以共享相同的格式设置。

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

人民网AIGC-X
人民网AIGC-X

国内科研机构联合推出的AI生成内容检测工具

下载
#include 
#include 
#include 
#include 

// 抽象享元类
class CharacterStyle {
public:
    virtual ~CharacterStyle() = default;
    virtual void display(const std::string& content) const = 0;
};

// 具体享元类
class ConcreteCharacterStyle : public CharacterStyle {
private:
    std::string font;
    int size;
    std::string color;

public:
    ConcreteCharacterStyle(const std::string& f, int s, const std::string& c)
        : font(f), size(s), color(c) {}

    void display(const std::string& content) const override {
        std::cout << "内容: " << content
                  << " [字体: " << font
                  << ", 大小: " << size
                  << ", 颜色: " << color << "]\n";
    }
};

// 享元工厂
class StyleFactory {
private:
    std::map> styles;

    // 生成唯一 key 表示一种样式
    std::string makeKey(const std::string& font, int size, const std::string& color) {
        return font + "-" + std::to_string(size) + "-" + color;
    }

public:
    std::shared_ptr getStyle(
        const std::string& font, int size, const std::string& color) {
        std::string key = makeKey(font, size, color);
        if (styles.find(key) == styles.end()) {
            styles[key] = std::make_shared(font, size, color);
        }
        return styles[key];
    }
};

客户端使用方式:

int main() {
    StyleFactory factory;

    auto style1 = factory.getStyle("宋体", 12, "黑色");
    auto style2 = factory.getStyle("宋体", 12, "黑色"); // 会复用 style1

    auto style3 = factory.getStyle("楷体", 14, "红色");

    style1->display("Hello");
    style2->display("World"); // 使用同一实例
    style3->display("!");

    // 验证是否为同一对象
    std::cout << "style1 和 style2 是否相同: " 
              << (style1.get() == style2.get() ? "是" : "否") << "\n";

    return 0;
}

关键点说明

享元模式在 C++ 中有效支持大量细粒度对象的关键在于:

  • 内部状态不可变:享元对象的内部状态应设为只读或构造后不变,以保证共享安全。
  • 使用智能指针管理生命周期:如 shared_ptr,避免内存泄漏,也方便工厂统一管理。
  • 工厂封装创建逻辑:客户端无需知道对象是否新建或复用,工厂内部完成查重和缓存。
  • 外部状态传参处理:display 方法接收 content 就是外部状态,不能放在享元内部。

适用场景与注意事项

享元模式适合以下情况:

  • 应用需要创建大量相似对象。
  • 对象的多数属性可以提取为外部状态。
  • 内存占用成为瓶颈,且对象存在可共享的内部状态。

但也要注意:

  • 增加了程序复杂性,需分离内外状态。
  • 并发环境下需考虑线程安全(如工厂中的 map 加锁)。
  • 若共享对象过多,工厂可能成为性能瓶颈
基本上就这些。C++ 中通过工厂 + 智能指针 + 值语义控制,能高效实现享元模式,显著降低内存开销。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1016

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

62

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

389

2025.12.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

74

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

28

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

59

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

35

2025.11.27

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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