Qt 的信号槽和 Boost.Signals 由于有着截然不同的设计目标,因此二者的实现、强度也十分不同。将二者混合在一起使用也不是不可能的,我们将在本系统的最后一部分来讨论这个问题。

使用信号槽

信号槽是伟大的工具,但是如何能更好的使用它们?相比于直接函数调用,有三点值得我们的注意。一个信号槽的调用:或许会比直接函数调用耗费更多的时间/空间;

可能不能使用 inline;

对于代码阅读者来说可能并不友好。

使用信号槽进行解耦,我们获得的最大的好处是,连接两端的对象不需要知道对方的任何信息。Button 同动作的连接是一个很典型的案例。例如如下信息:class Elevator

{

public:

enum Direction { DownDirection=-1, NoDirection=0, UpDirection=1 };

enum State { IdleState, LoadingState, MovingState };

// ...

// signals:

void floorChanged(int newFloor );

void stateChanged( State newState );

void directionChanged( Direction newDirection );

};

Elevator 类,也就是电梯,不需要知道有多少显示器正在监听它的信号,也不需要知道这些显示器的任何信息。每一层可能有一个屏幕和一组灯,用于显示电梯的当前位置和方向,另外一些远程操控的面板也会显示出同样的信息。电梯并不关心这些东西。当它穿过(或者停在)某一层的时候,它会发出一个 floorChanged(int) 信号。或许,交通信号灯是更合适的一个例子。

你也可以实现一个应用程序,其中每一个函数调用都是通过信号来触发的。这在技术上说是完全没有问题的,然而却是不大可行的,因为信号槽的使用无疑会丧失一部分代码可读性和系统性能。如何在这其中做出平衡,也是你需要考虑的很重要的一点。

Qt 方式

了解 Qt 信号槽最好的莫过于 Qt 的文档。不过,这里我们从一个小例子来了解信号槽的 Qt 方式的使用。// Qt Signals and Slots

class Button :public QObject

{

Q_OBJECT

Q_SIGNALS:

void clicked();

};

class Page :public QObject

{

Q_OBJECT

public Q_SLOTS:

void reload();

};

// given pointers to an actual Button and Page:

connect(button,SIGNAL(clicked()), page, SLOT(reload()));

Boost.Signals 方式

了解 Boost.Signals 的最好方式同样是 Boost 的文档。这里,我们还是先从代码的角度了解一下它的使用。// Boost.Signals

class Button

{

public:

boost::signal clicked;

};

class Page

{

public:

void reload();

};

// given pointers to an actual Button and Page:

button->clicked.connect( boost::bind(&Page::reload, page));

对比

或许你已经注意到上面的例子中,无论是 Qt 的实现方式还是 Boost 的实现方式,除了必须的 Button 和 Page 两个类之外,都不需要额外的类。两种实现都解决了类爆炸的问题。下面让我们对照着来看一下我们前面的分析。现在我们有:两个不同的术语以及各自的动作:信号和槽;

在一个地方(信号)可以连接零个或者多个回调函数(槽),同时也是多对多的;

焦点在于连接本身,而不是提供者或者消费者;

不需要手工为了一个连接创建新的类;

连接仍旧是类型安全的。

这五点是信号槽系统的核心,Qt 和 boost 都拥有这些特性。下面则是二者的不同之处:

Boost.SignalsQt Signals 和 Slots

一个信号就是一个对象信号只能是成员函数

发出信号类似于函数调用发出信号类似于函数调用,Qt 提供了一个 emit 关键字来完成这个操作

信号可以是全局的、局部的或者是成员对象信号只能是成员函数

任何能够访问到信号对象的代码都可以发出信号只有信号的拥有者才能发出信号

槽是任何可被调用的函数或者函数对象槽是经过特别设计的成员函数

可以有返回值,返回值可以在多个槽中使用没有返回值

同步的同步的或者队列的

非线程安全线程安全,可以跨线程使用

当且仅当槽是可追踪的时候,槽被销毁时,连接自动断开槽被销毁时,连接都会自动断开(因为所有槽都是可追踪的)

类型安全(编译器检查)类型安全(运行期检查)

参数列表必须完全一致槽可以忽略信号中多余的参数

信号、槽可以是模板信号、槽不能是模板

C++ 直接实现通过由 moc 生成的元对象实现(moc 以及元对象系统都是 C++ 直接实现的)

没有内省机制可以通过内省发现

可以通过元对象调用 连接可以从资源文件中自动推断出

最重要的是,Qt 的信号槽机制已经深深地植入到框架之中,成为不可分割的一部分。它们可以使用 Qt 专门的开发工具,例如 QtCreator,通过拖拽的方式很轻松的创建、删除、修改。它们甚至可以通过动态加载资源文件,由特定命名的对象自动动态生成。这些都是 boost 作为一个通用库所不可能提供的。

linux下qt加载boost,信号槽的实现实例—— Qt 和 Boost相关推荐

  1. linux path环境变量检索目录,Linux下动态链接库加载路径及搜索路径问题

    引子 近日,服务器迁移后,偷懒未重新编译nginx的,直接./nginx启动,结果遇到如下问题: "error while loading shared libraries" 这是 ...

  2. javaweb项目如何实现简单的验证码(以及eclipse和Linux下验证码加载不出来)

    像这样简单的验证码如何生成并显示在页面上并能点击不断刷新验证码呢? 1.首先创建一个servlet包并创建一个VerificationCodeServlet package codewen.bookc ...

  3. Linux下无法加载Qt platform plugin “xcb“

    问题描述 Linux下使用虚拟环境中的labelme,会出现 Could not load the Qt platform plugin "xcb" in "" ...

  4. Nginx 负载均衡 - linux下nginx加载配置文件异常处理,提示invalid PID number in “/run/nginx.pid“问题解决

    执行 nginx -s reload 加载配置文件的时候报错了. 提示 nginx: [error] invalid PID number "" in "/run/ngi ...

  5. QT加载muPDF库和对muPDF的调用

    http://jinzeyu.cn/index.php/archives/126/ 以下链接都是我过去写的,第一个讨论加载,第二个解决了更多问题,这次我要简单分享一下如何写代码. QT加载muPDF- ...

  6. Linux系统下如何加载U盘或移动硬盘

    Linux系统下如何加载U盘或移动硬盘 2007-05-15 00:00作者:赵彪出处:论坛整理责任编辑:原野 - 1.在插入U盘或硬盘之前,在命令行窗口运行:fdisk -l 命令,系统将显示目前所 ...

  7. Boost:使用Qt加载图像,应用简单的框模糊滤镜

    Boost:使用Qt加载图像,应用简单的框模糊滤镜 实现功能 C++实现代码 实现功能 ,Boost的compute模块使用Qt加载图像,应用简单的框模糊滤镜 C++实现代码 #include < ...

  8. cad重新加载php命令,linux修改php.ini后重新加载配置文件命令 如何在不cad的况下重新加载acad...

    延伸:如何在不cad的况下重新加载acad 问题:我在绘图过程中想要调整acad.pgp,担 但修改后需要 重新启 回答:能不能再说清楚点,我不太懂!例如:ET工具或者Bonus工具在哪里? 查看原帖 ...

  9. QT源码剖析-QT对象通信机制信号槽的绑定具体实现

    本文详细介绍QT核心机制之一 信号和槽. 我们在此根据Qt源代码一步一步探究其信号槽的实现过程. 核心知识点: 模板元编程技术. Qt moc预编译机制. QObject类. 目录 1. QObjec ...

最新文章

  1. ASP.NET Core 替换 Action 实际执行方法
  2. 关于如何清除某个特定网站的缓存---基于Chrome浏览器
  3. 对java这门课程的认识_关于java课程的总结
  4. Spring Boot中使用模板引擎参数化传参数
  5. JavaScript高级程序设计之EventUtil
  6. django 1.8 官方文档翻译:13-12 验证器
  7. Tpcc-mysql 结果解读
  8. linux内存脚本下载,linux tmpfs及消耗内存脚本
  9. sql for循环_【赵强老师】什么是PL/SQL?
  10. linux gdb 导出到文件怎么打开,GDB基本命令从打开文件到调试结束的教程
  11. matlab 一维 fft,matlab - 一维信号的频谱分析(FFT等) - 堆栈内存溢出
  12. Xiaojie雷达之路---车载雷达信号处理流程
  13. 手机内存垃圾不会清理?学会删除这几个文件夹,瞬间腾出几个G
  14. 均值场博弈_平均场博弈(mean field game)
  15. 机器人门禁控制盒怎么接线方法_门禁电锁如何接线
  16. 达观数据智能对公审贷系统,深化上海银行普惠金融、供应链金融科技创新
  17. 小白理解k-svd算法
  18. JAVA实现功能的方法
  19. 网络口碑营销推广,品牌营销选对方式很重要
  20. /opt/MegaRAID/MegaCli/MegaCli64

热门文章

  1. 【less-11】基于SQLI的POST字符型SQL注入
  2. [高精度整数] N的阶乘 [2006年清华大学计算机研究生机试真题]
  3. 自考----怎么说我不爱你
  4. Visual Studio 2008安装Boost _1_45_0
  5. 【java】各种对文件,读写的方法及小例子
  6. javascript函数参数的传递问题
  7. IntelliJ IDEA 初始化项目时No Java SDK Found
  8. [poj 2796]单调栈
  9. React.js 入门与实战之开发适配PC端及移动端新闻头条平台课程上线了
  10. 转载关于通过判断浏览器的userAgent,用正则来判断是否是ios和Android客户端