享元模式通过共享内部状态减少内存占用,C++中用工厂类结合静态map缓存实例。内部状态(如字符样式)共享存储,外部状态(如位置坐标)运行时传入,实现大量相似对象的高效管理。
当需要创建大量相似对象时,直接实例化会消耗大量内存。享元模式通过共享相同状态的对象来减少内存占用,C++中可通过工厂类结合静态存储实现。
享元模式核心思想
将对象的状态分为内部状态和外部状态:
• 内部状态:可共享,通常作为享元对象的成员变量,不会随环境改变
• 外部状态:不可共享,由客户端在运行时传入,决定对象的行为表现
例如文本编辑器中的字符样式(字体、大小、颜色)是内部状态,位置坐标是外部状态。
基本结构实现
定义享元接口,通常包含一个操作方法接收外部状态:
立即学习“C++免费学习笔记(深入)”;
“`cpp class CharacterFlyweight { public: virtual ~CharacterFlyweight() = default; virtual void display(int x, int y) const = 0; // x,y为外部状态 }; “`
具体享元类存储内部状态,构造时初始化:
“`cpp class ConcreteCharacter : public CharacterFlyweight { private: char symbol; std::string font; int size;
public: ConcreteCharacter(char s, const std::string& f, int sz) : symbol(s), font(f), size(sz) {}
void display(int x, int y) const override { std::cout << "Draw '" << symbol << "' at (" << x << "," << y << ") with font=" << font << ", size=" << size << "n"; }
};
<H3>享元工厂管理实例</H3> <p>使用静态map缓存已创建的享元对象,避免重复生成:</p> ```cpp class FlyweightFactory { private: static std::map<std::string, std::shared_ptr<CharacterFlyweight>> pool; public: static std::shared_ptr<CharacterFlyweight> getCharacter( char symbol, const std::string& font, int size) { std::string key = std::string(1, symbol) + "_" + font + "_" + std::to_string(size); if (pool.find(key) == pool.end()) { pool[key] = std::make_shared<ConcreteCharacter>(symbol, font, size); } return pool[key]; } }; // 静态成员定义 std::map<std::string, std::shared_ptr<CharacterFlyweight>> FlyweightFactory::pool;
使用示例与效果
客户端通过工厂获取享元对象,传入外部状态调用行为:
“`cpp int main() { auto ch1 = FlyweightFactory::getCharacter(‘A’, “Arial”, 12); auto ch2 = FlyweightFactory::getCharacter(‘A’, “Arial”, 12); // 共享同一实例 auto ch3 = FlyweightFactory::getCharacter(‘B’, “Arial”, 12);
ch1->display(0, 0); // 外部状态不同 ch2->display(10, 0); // 但共享内部状态 ch3->display(20, 0); return 0;
}
<p>输出显示虽然创建了三个逻辑字符,但'A'只有一份内部数据,节省了存储空间。</p> <p>基本上就这些。关键在于分离变与不变的部分,用工厂控制实例唯一性,适合处理重复度高的细粒度对象。</p>
ai c++ 内存占用 red String 成员变量 const auto char int void 接口 class public private map symbol 对象 default display