C++观察者模式:原理、实现与游戏开发应用
1. 观察者模式的核心概念解析观察者模式Observer Pattern是C中最重要的行为型设计模式之一它定义了对象间一对多的依赖关系。当被观察对象状态改变时所有依赖它的对象都会自动收到通知并更新。这种模式在GUI事件处理、消息队列、游戏开发等场景中应用广泛。我在实际项目中最常用的场景是游戏引擎开发。比如当玩家角色属性变化时需要实时更新UI界面、保存游戏状态、触发成就系统等。观察者模式完美解决了这种一对多的通知需求避免了硬编码的调用链。2. C实现观察者模式的经典结构2.1 基础类设计标准的观察者模式包含两个核心类// 观察者基类抽象接口 class Observer { public: virtual ~Observer() default; virtual void update(const std::string message) 0; }; // 被观察者基类 class Subject { private: std::vectorObserver* observers_; public: void attach(Observer* observer) { observers_.push_back(observer); } void detach(Observer* observer) { observers_.erase( std::remove(observers_.begin(), observers_.end(), observer), observers_.end()); } void notify(const std::string message) { for (auto observer : observers_) { observer-update(message); } } };2.2 实际应用示例假设我们开发一个气象站系统当温度变化时需要通知多个显示设备// 具体被观察者 class WeatherStation : public Subject { private: float temperature_; public: void setTemperature(float temp) { temperature_ temp; notify(Temperature updated: std::to_string(temp)); } }; // 具体观察者 class DisplayDevice : public Observer { public: void update(const std::string message) override { std::cout Display received: message std::endl; } }; class Logger : public Observer { public: void update(const std::string message) override { std::cout Logging: message std::endl; } };3. 现代C的优化实现3.1 使用智能指针管理生命周期原始指针容易导致内存泄漏建议改用shared_ptrclass Subject { private: std::vectorstd::shared_ptrObserver observers_; // ...其余实现相同 };3.2 使用lambda简化观察者注册C11后可以更优雅地实现临时观察者auto consoleObserver std::make_sharedObserver(); subject.attach(consoleObserver); // 使用lambda subject.attach(std::make_sharedObserver( [](const std::string msg) { std::cout Lambda observer: msg; } ));4. 实际项目中的经验技巧4.1 线程安全实现多线程环境下需要加锁#include mutex class ThreadSafeSubject { private: std::vectorstd::shared_ptrObserver observers_; std::mutex mtx_; public: void attach(std::shared_ptrObserver observer) { std::lock_guardstd::mutex lock(mtx_); observers_.push_back(observer); } // ...其他方法也需要类似保护 };4.2 性能优化建议批量通知当状态频繁变化时可以积累变化后一次性通知差异化更新给update()添加参数标识变化类型避免不必要的处理弱引用观察者对于可能失效的观察者使用weak_ptr避免内存泄漏5. 观察者模式在游戏开发中的典型应用5.1 玩家状态监控class Player { private: int health_; std::vectorstd::shared_ptrObserver observers_; public: void takeDamage(int damage) { health_ - damage; notify(Health changed: std::to_string(health_)); if(health_ 0) { notify(Player died); } } }; // 成就系统观察者 class AchievementSystem : public Observer { public: void update(const std::string message) override { if(message Player died) { unlockAchievement(First Death); } } };5.2 游戏事件系统更复杂的游戏通常会抽象出专门的事件总线class GameEventBus { private: std::unordered_mapstd::string, std::vectorstd::functionvoid(const Event) handlers_; public: void subscribe(const std::string eventType, std::functionvoid(const Event) handler) { handlers_[eventType].push_back(handler); } void publish(const Event event) { auto it handlers_.find(event.type); if(it ! handlers_.end()) { for(auto handler : it-second) { handler(event); } } } };6. 常见问题与解决方案6.1 循环引用问题当观察者和被观察者相互持有时可能导致内存泄漏// 错误示例 class BadObserver : public Observer { private: Subject subject_; // 保持对subject的引用 public: BadObserver(Subject sub) : subject_(sub) { subject_.attach(this); // 相互引用 } };解决方案使用weak_ptr打破循环在析构时显式detach6.2 通知顺序问题多个观察者的通知顺序是不确定的如果存在依赖关系// 确保UI在数据保存后更新 subject.attach(dataSaver); // 先加入的先通知 subject.attach(uiUpdater); // 后加入的后通知6.3 性能瓶颈排查当观察者数量很多时通知可能成为性能瓶颈。可以通过使用profiler分析热点实现分级通知机制考虑使用发布-订阅模式的变体7. 观察者模式的替代方案虽然观察者模式很强大但在某些场景下可能有更好的选择信号槽系统如Qt的信号槽类型安全更好事件总线更适合大型系统的解耦反应式编程如RxCpp提供更强大的数据流处理在最近的一个跨平台项目中我最终选择了基于boost::signals2的实现因为它提供了线程安全的信号槽机制同时避免了手动管理观察者列表的麻烦。

相关新闻

AI编程助手持久记忆系统:基于向量数据库与RAG的工程实践

AI编程助手持久记忆系统:基于向量数据库与RAG的工程实践

1. 从“健忘症”到“持久记忆”:AI编程助手的进化瓶颈如果你用过市面上主流的AI编程助手,无论是GitHub Copilot、Cursor,还是各种大模型驱动的IDE插件,大概率都经历过这种“抓狂”时刻:你花了一下午,在一个…

2026/8/10 5:16:39 阅读更多 →
黄山合肥深度游:行程规划与美食体验全攻略

黄山合肥深度游:行程规划与美食体验全攻略

1. 行程规划与地域特色解析黄山作为中国顶级山岳景观代表,其游览路线设计需要兼顾体力分配与景观价值最大化。传统旅行团常见的"一日游"模式往往导致游客疲于奔命,而9天的时长为我们提供了深度体验的可能。1.1 黄山段行程设计要点建议采用&quo…

2026/8/10 5:16:39 阅读更多 →
哈希表实现最长连续序列算法解析

哈希表实现最长连续序列算法解析

1. 题目解析与解题思路1.1 题目要求理解给定一个未排序的整数数组 nums,我们需要找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。例如:输入:[100, 4, 200, 1, 3, 2]输出:4解释:最…

2026/8/10 5:16:39 阅读更多 →

最新新闻

斯坦福前沿AI系统讲座:大模型部署、微调与AI Agent工程实践指南

斯坦福前沿AI系统讲座:大模型部署、微调与AI Agent工程实践指南

这次我们来看一个来自斯坦福大学的前沿系统讲座系列。这个系列汇集了2026年产业界顶级专家的真知灼见,内容横跨AI、大模型、AI原生系统等多个炙手可热的领域。对于开发者、研究者以及技术决策者而言,这不仅仅是一场知识盛宴,更是一份理解未来…

2026/8/10 6:22:10 阅读更多 →
LLM工作模式实战:从聊天到结构化技术协作的工程化指南

LLM工作模式实战:从聊天到结构化技术协作的工程化指南

在实际项目开发、技术文档编写和日常问题排查中,很多开发者已经将大型语言模型(LLM)作为辅助工具。然而,直接使用面向公众的通用聊天界面,常常会遇到上下文管理混乱、对话风格不专业、代码格式丢失、历史记录难以追溯等…

2026/8/10 6:22:10 阅读更多 →
工业数智化核心:时序数据库IoTDB的架构、查询与AI集成实战

工业数智化核心:时序数据库IoTDB的架构、查询与AI集成实战

1. 从数据孤岛到智能决策:工业数智化为何绕不开时序数据?上周在杭州参加了一场名为“Data Meets AI”的技术沙龙,现场讨论的热度远超预期。作为一位在工业软件和数据平台领域摸爬滚打了十几年的老兵,我最大的感触是,大…

2026/8/10 6:22:10 阅读更多 →
绕过WSL在Windows安装Docker的完整指南

绕过WSL在Windows安装Docker的完整指南

1. 为什么需要绕过WSL安装Docker? 在Windows系统上运行Docker的传统方案是通过WSL(Windows Subsystem for Linux)后端。但实际工作中,我们经常会遇到以下几种必须绕过WSL的情况: 企业IT策略限制:部分公司…

2026/8/10 6:22:10 阅读更多 →
数据库索引创建与性能优化实战指南

数据库索引创建与性能优化实战指南

1. 索引创建与数据更新实验概述上周在数据库原理课上做完索引实验后,有几个学弟跑来问我:"为什么明明建了索引,查询速度反而变慢了?"这个问题让我想起自己第一次做索引实验时踩过的坑。今天就把这个实验的完整操作和避坑…

2026/8/10 6:22:10 阅读更多 →
Claude Code权限模式更新:从手动确认到自动执行的AI编程助手变革

Claude Code权限模式更新:从手动确认到自动执行的AI编程助手变革

如果你最近在开发中遇到 Claude Code 权限弹窗变多,或者发现它突然能自动执行一些文件操作而无需你手动确认,别慌,这不是 Bug,而是一次重要的策略调整。2024年8月14日,Anthropic 对其代码助手 Claude Code 的默认权限模…

2026/8/10 6:21:10 阅读更多 →

日新闻

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南 【免费下载链接】graphql-css A blazing fast CSS-in-GQL™ library. 项目地址: https://gitcode.com/gh_mirrors/gr/graphql-css GraphQL-CSS是一个基于GraphQL的CSS-in-GQL™库&#xff0…

2026/8/10 0:00:02 阅读更多 →
告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南 【免费下载链接】kiss-translator A simple, open source bilingual translation extension & Greasemonkey script (一个简约、开源的 双语对照翻译扩展 & 油猴脚本) 项目地址: https://gitcode.com/…

2026/8/10 0:00:02 阅读更多 →
BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案 【免费下载链接】BepInEx.ConfigurationManager Plugin configuration manager for BepInEx 项目地址: https://gitcode.com/gh_mirrors/be/BepInEx.ConfigurationManager 你是否曾经因为游戏插件的复杂…

2026/8/10 0:00:02 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/10 1:05:29 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/10 1:05:29 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/10 1:05:29 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/9 17:05:02 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/10 1:05:29 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/9 17:05:02 阅读更多 →