讲师中心 微信公众号

工具推荐

视频效率加速
updream

一键生成高质量推广成片

立刻MV
立刻MV

低成本歌曲 MV、视频生成

Laper
Laper

剧本策划到成片协作

AniShort
AniShort

AI短剧协同制作平台

怎样用C++实现享元模式 对象池与内存优化实践

老浩姑娘_1628

老浩姑娘_1628

发布时间:2025-07-02 09:18:41

|

777人浏览过

|

来源于php中文网

原创

享元模式通过共享技术有效支持大量细粒度对象,核心在于减少对象创建和销毁以优化内存和性能。1. 定义享元接口,声明与状态无关的操作;2. 创建具体享元类,仅包含可共享的内部状态;3. 实现享元工厂,维护享元池实现对象复用;4. 客户端通过工厂获取对象并传入外部状态。对象池进一步优化内存:避免频繁分配释放、减少碎片、提升性能。多线程下可通过锁机制、线程安全数据结构或原子操作保障安全。应用场景包括文本编辑器、游戏开发、数据库连接池、编译器及图形处理等领域。

怎样用C++实现享元模式 对象池与内存优化实践

享元模式的核心在于通过共享技术有效地支持大量细粒度的对象。在C++中,这通常涉及到对象池的使用,以减少对象的创建和销毁,从而优化内存使用和提高性能。

怎样用C++实现享元模式 对象池与内存优化实践

解决方案:

怎样用C++实现享元模式 对象池与内存优化实践
  1. 定义享元接口:

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

    首先,定义一个享元接口,声明享元对象需要实现的方法。这些方法通常是与对象的状态无关的操作。

    怎样用C++实现享元模式 对象池与内存优化实践
    class Flyweight {
    public:
        virtual void operation(int extrinsicState) = 0;
        virtual ~Flyweight() {}
    };
  2. 创建具体享元类:

    实现享元接口的具体类。这些类应该只包含内部状态(intrinsic state),即可以共享的状态。

    class ConcreteFlyweight : public Flyweight {
    private:
        int intrinsicState;
    public:
        ConcreteFlyweight(int state) : intrinsicState(state) {}
        void operation(int extrinsicState) override {
            // 使用内部状态和外部状态进行操作
            std::cout << "ConcreteFlyweight: Intrinsic = " << intrinsicState
                      << ", Extrinsic = " << extrinsicState << std::endl;
        }
    };
  3. 实现享元工厂:

    C++14
    C++14

    C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

    下载

    享元工厂负责创建和管理享元对象。它维护一个享元池,如果请求的享元对象已经存在,则直接返回,否则创建新的享元对象并添加到池中。

    #include <map>
    
    class FlyweightFactory {
    private:
        std::map<int, Flyweight*> flyweights;
    public:
        Flyweight* getFlyweight(int key) {
            if (flyweights.find(key) == flyweights.end()) {
                flyweights[key] = new ConcreteFlyweight(key);
            }
            return flyweights[key];
        }
    
        ~FlyweightFactory() {
            for (auto& pair : flyweights) {
                delete pair.second;
            }
            flyweights.clear();
        }
    };
  4. 客户端代码:

    客户端通过享元工厂获取享元对象,并传递外部状态(extrinsic state)给享元对象,进行操作。

    int main() {
        FlyweightFactory factory;
        Flyweight* flyweight1 = factory.getFlyweight(1);
        flyweight1->operation(10);
    
        Flyweight* flyweight2 = factory.getFlyweight(2);
        flyweight2->operation(20);
    
        Flyweight* flyweight3 = factory.getFlyweight(1); // 共享对象
        flyweight3->operation(30);
    
        return 0;
    }

对象池如何进一步优化内存?

对象池通过预先创建一组对象并将其保存在池中,避免了频繁的对象创建和销毁。当需要对象时,直接从池中获取,使用完毕后归还到池中,而不是销毁。

  • 减少内存分配和释放: 对象的创建和销毁涉及系统调用,开销较大。对象池可以显著减少这些操作。
  • 避免内存碎片: 频繁的内存分配和释放容易产生内存碎片,降低内存利用率。对象池可以减少碎片化。
  • 提高性能: 对象池可以快速提供对象,避免了等待内存分配的时间。

如何处理多线程环境下的享元模式和对象池?

在多线程环境下,需要考虑线程安全问题。

  • 锁机制: 可以使用互斥锁(mutex)来保护享元池的访问,确保同一时间只有一个线程可以访问池。
  • 线程安全的数据结构: 使用线程安全的数据结构,例如std::mutex保护的std::map或std::queue。
  • 原子操作: 对于简单的计数器等操作,可以使用原子操作(atomic operations)。
#include <iostream>
#include <map>
#include <mutex>

class ThreadSafeFlyweightFactory {
private:
    std::map<int, Flyweight*> flyweights;
    std::mutex mutex;

public:
    Flyweight* getFlyweight(int key) {
        std::lock_guard<std::mutex> lock(mutex); // 加锁
        if (flyweights.find(key) == flyweights.end()) {
            flyweights[key] = new ConcreteFlyweight(key);
        }
        return flyweights[key];
    }

    ~ThreadSafeFlyweightFactory() {
        std::lock_guard<std::mutex> lock(mutex); // 加锁
        for (auto& pair : flyweights) {
            delete pair.second;
        }
        flyweights.clear();
    }
};

享元模式在实际项目中的应用场景有哪些?

  • 文本编辑器: 字符对象可以作为享元对象,共享字体、大小、颜色等属性。
  • 游戏开发: 游戏中的大量相同类型的对象,例如树木、石头等,可以共享模型数据。
  • 数据库连接池: 数据库连接对象可以作为享元对象,避免频繁创建和销毁连接。
  • 编译器: 语法树中的节点可以共享一些属性。
  • 图形图像处理: 图形对象可以共享颜色、纹理等属性。

热门AI工具

更多
切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

相关专题

更多
treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2901

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

416

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

437

2026.01.06

C++ 数据结构与算法实现教程合集
C++ 数据结构与算法实现教程合集

以 C++ 为实现语言,系统讲解核心数据结构与算法,涵盖链表(单链表/双链表/环检测)、栈与队列(单调栈/优先队列)、二叉树(遍历/BST/AVL/红黑树)、哈希表(开地址法/链地址法)、图(邻接表/BFS/DFS/Dijkstra/拓扑排序)、常见排序算法(快排/归并/堆排/计数排序)的实现与复杂度分析,同时分享 LeetCode 刷题技巧、竞赛编程常用模板(二分/前缀和/滑动窗口/动态规划),帮助开发者夯实算法基础。

492

2026.05.09

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

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

3248

2023.10.19

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

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

5469

2025.10.17

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

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

3909

2025.12.29

java接口相关教程
java接口相关教程

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

506

2026.01.19

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

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

精品课程

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn