0

0

C++怎么使用观察者模式_C++事件处理教程【响应】

尼克

尼克

发布时间:2026-02-23 16:03:10

|

532人浏览过

|

来源于php中文网

原创

观察者模式在c++中需手动实现接口、指针管理和生命周期控制;典型错误包括悬空指针和漏通知,推荐用std::weak_ptr存储观察者并及时清理。

c++怎么使用观察者模式_c++事件处理教程【响应】

观察者模式在 C++ 里不是靠语言特性,而是靠接口 + 指针/引用 + 容器手动搭

它没有 event 关键字,也不像 C# 那样有 += 语法糖。你得自己定义通知接口、维护观察者列表、处理生命周期——否则很容易崩溃或漏通知。

典型错误现象:Segmentation fault(观察者已析构但还在列表里)、notify() 调用后行为没反应(忘了调 registerObserver() 或对象被提前释放)。

  • 观察者必须是堆对象或确保生命周期长于被观察者,栈对象注册后立即析构 = 悬空指针
  • 推荐用 std::weak_ptr<observer></observer> 存储观察者,避免循环引用;被观察者用 std::shared_ptr 管理自身时尤其关键
  • std::vector<:weak_ptr>></:weak_ptr> 是最常用容器,遍历时先 lock(),失败就 erase 对应项

怎么写一个最小可用的 Observer/Subject 接口

别一上来就抽象成模板类或支持泛型事件。先搞定「状态变更 → 通知所有活着的观察者」这个核心链路。

示例中 Subject 不持有具体业务逻辑,只管注册、移除、广播;Observer 只暴露纯虚函数 onStateChanged()

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

MyMap AI
MyMap AI

使用AI将想法转化为图表

下载
class Observer {
public:
    virtual ~Observer() = default;
    virtual void onStateChanged(int newState) = 0;
};
<p>class Subject {
std::vector<std::weak<em>ptr<Observer>> observers</em>;
public:
void attach(std::shared<em>ptr<Observer> obs) {
observers</em>.push<em>back(obs);
}
void notify(int state) {
for (auto it = observers</em>.begin(); it != observers<em>.end();) {
auto obs = it->lock();
if (obs) {
obs->onStateChanged(state);
++it;
} else {
it = observers</em>.erase(it); // 自动清理失效项
}
}
}
};</p>

std::function + lambda 能替代 Observer 接口吗?能,但要小心捕获

可以,而且更轻量。但 lambda 捕获局部变量或 this 时极易产生悬空引用。

常见错误:在函数内注册一个捕获了局部 int x 的 lambda,函数返回后通知触发,访问已销毁的 x

  • 只捕获值([x]() { ... })或静态/全局对象是安全的
  • 捕获 this 必须确保被观察者生命周期严格长于 lambda 存活期;否则改用 std::weak_ptr<self></self> 在 lambda 内部 lock()
  • 存储 lambda 用 std::vector<:function>></:function>,但无法在运行时区分或移除特定回调 —— 所以需要额外 key 或用 map 管理

Qt 的 signals/slots 算不算观察者模式?用的时候要注意什么

算,而且是高度封装的版本。但它依赖 QObject 继承和元对象系统,跟手写模式不是一回事。

容易踩的坑:connect() 默认是 Qt::AutoConnection,跨线程时若没显式指定 Qt::QueuedConnection,可能直接在发送线程调用槽函数,导致 UI 线程被阻塞或非 QObject 派生对象访问异常。

  • 信号参数类型必须完全匹配槽函数签名(C++11 后允许隐式转换,但不建议依赖)
  • 连接前检查 senderreceiver 是否为 nullptr,Qt5+ 不再自动判空
  • QObject::disconnect() 显式断开,或依赖父子关系自动清理;否则对象析构后信号仍可能触发已释放内存

多线程下清空观察者列表、跨线程发通知、lambda 捕获生命周期——这三个点,随便漏掉一个,程序就可能跑几天才崩,或者只在特定优化等级下出错。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
视频后缀名都有哪些
视频后缀名都有哪些

视频后缀名都有avi、mpg、mpeg、rm、rmvb、flv、wmv、mov、mkv、ASF、M1V、M2V、MPE、QT、VOB、RA、RMJ、RMS、RAM、等等。更多关于视频后缀名的相关知识,详情请看本专题下面的文章,php中文网欢迎大家前来学习。

3775

2023.10.31

C++ Qt图形开发
C++ Qt图形开发

本专题专注于 C++ Qt框架在图形界面开发中的应用,系统讲解窗口设计、信号与槽机制、界面布局、事件处理、数据库连接与跨平台打包等核心技能,通过多个桌面应用项目实战,帮助学员快速掌握 Qt 框架并独立完成跨平台GUI软件的开发。

72

2025.08.15

C++ 图形界面开发基础(Qt方向)
C++ 图形界面开发基础(Qt方向)

本专题系统讲解 使用 C++ 与 Qt 进行图形界面(GUI)开发的核心技能,内容涵盖 Qt 项目结构、窗口组件、信号与槽机制、事件处理、布局管理、资源管理,以及跨平台编译与打包流程。通过多个小型桌面应用实战案例,帮助学习者掌握从界面设计到功能实现的完整 GUI 开发能力。

94

2025.12.05

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

830

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

580

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

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

294

2025.08.29

C++中int的含义
C++中int的含义

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

210

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

183

2023.11.23

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

1127

2026.02.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 10万人学习

C 教程
C 教程

共75课时 | 4.9万人学习

C++教程
C++教程

共115课时 | 19.1万人学习

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

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