0

0

C++怎么实现委托模式_C++行为封装教程【解耦】

冰火之心

冰火之心

发布时间:2026-03-04 04:35:23

|

708人浏览过

|

来源于php中文网

原创

c++中std::function+std::bind是最轻量委托实现,但需严控对象生命周期;函数指针零开销但无状态捕获能力;std::function有类型擦除开销,高频场景应避免反复构造;信号-槽机制非委托替代品,适用多播而非单目标调用。

c++怎么实现委托模式_c++行为封装教程【解耦】

std::function + std::bind 能直接当委托用,但要注意对象生命周期

委托本质是「把函数调用延迟并解耦到另一处执行」,C++ 没原生 delegate 关键字,但 std::function 配合 std::bind 或 lambda 就是最常用、最轻量的实现方式。它不依赖第三方库,C++11 起就可用。

常见错误是绑定成员函数时传入了临时或已销毁对象的 this 指针,导致调用时崩溃或未定义行为——比如在回调里访问 this->data,但对象早被析构了。

  • std::shared_ptr 管理被委托对象的生命周期,再用 std::weak_ptr 在 lambda 里捕获,调用前 lock() 判断是否还活着
  • 避免直接 std::bind(&Class::func, this, ...),尤其当 this 所指对象生命周期不可控时
  • 如果委托只用于同一线程且生命周期明确(如 GUI 控件回调绑定到窗口对象),直接捕获 this 是可接受的,但得确保调用点不会晚于对象销毁
auto cb = [ptr = shared_from_this()](int x) {
    if (auto p = ptr.lock()) {
        p->handle(x);
    }
};

用函数指针模拟 C 风格委托,但无法捕获状态

纯函数指针(如 void (*)(int))是最底层的委托形式,零开销、兼容 C ABI,适合嵌入式或与 C 库对接(比如注册 qsort 的比较函数)。但它不能带捕获,也不能指向成员函数——这是硬限制,不是写法问题。

容易踩的坑是试图把 lambda(哪怕没捕获)直接转成函数指针:只有无捕获 lambda 才能隐式转,且必须类型严格匹配;一旦加了 [=][&],编译就报错 cannot convert lambda to function pointer

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

AI Undetect
AI Undetect

让AI无法察觉,让文字更人性化,为文字体验创造无限可能。

下载
  • 需要状态时,必须额外传一个 void* 上下文参数(如 POSIX qsort 的第 4 个参数),由使用者自己做类型转换和生命周期管理
  • 成员函数想塞进去?得写一个静态包装器,把 void* 强转回对象指针再调用,手动维护对象存活
  • 性能上比 std::function 略高(无类型擦除开销),但代码更脆、易出错

std::function 的类型擦除有开销,高频调用场景要测

std::function 内部用类型擦除实现多态,每次构造、拷贝、调用都有间接成本。在游戏循环、音频处理或每秒数万次的事件分发中,这个开销可能从纳秒级变成微秒级,积少成多。

不是所有场景都敏感,但如果你发现 profiler 里 std::function::operator() 占比异常高,就得警惕。这时候别急着换方案,先确认是不是误用了拷贝(比如反复传值而非 const 引用)或过度封装。

  • 高频路径上,优先用函数指针或模板参数(如策略类模板)替代 std::function
  • 避免在循环内反复构造 std::function 对象;提前存为成员变量或局部静态变量
  • Clang/GCC 下开启 -O2 后,简单 lambda 的 std::function 调用常能内联,但绑定成员函数 + 捕获变量后基本无法内联

信号-槽机制(如 libsigc++ 或 Qt)不是委托,别混用

Qt 的 connect 或 libsigc++ 的 signal 是多播(multiple subscribers)、带连接管理、支持跨线程的信号系统,而委托是单目标、一对一的调用包装。强行用信号当委托,等于用卡车送快递——功能过剩,还多一堆引用计数、线程队列、元对象系统开销。

典型误用:给每个按钮点击写一个 Signal<void></void>,只为绑定一个 handler。这时 std::function<void></void> 更直白、内存更紧凑、析构更快。

  • 需要广播、断连、自动清理(如对象销毁时自动断开所有槽)才上信号系统
  • Qt 中 QObject::connect 绑定普通函数或 lambda 时,底层仍走 std::function 类似逻辑,但多了元信息注册和事件循环调度
  • 跨线程投递信号会触发队列+事件循环,而委托调用永远是同步的,这点必须清楚

委托真正的复杂点不在语法,而在谁拥有调用权、谁负责生命周期、调用栈深度是否可控——这些没法靠模板推导或编译器检查,全靠设计时想清楚。写完记得问一句:这个回调,到底该在哪儿析构?

热门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中文网欢迎大家前来学习。

3835

2023.10.31

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

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

76

2025.08.15

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

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

103

2025.12.05

java多态详细介绍
java多态详细介绍

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

27

2025.11.27

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

557

2023.09.20

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

557

2023.09.20

string转int
string转int

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

910

2023.08.02

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

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

599

2024.08.29

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

3

2026.03.03

热门下载

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

精品课程

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

共94课时 | 10.6万人学习

C 教程
C 教程

共75课时 | 5.1万人学习

C++教程
C++教程

共115课时 | 20.3万人学习

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

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