c++信号槽的使用方法

 

C++信号槽使用方法

 

1.       为什么要使用信号槽.   

a.       可以将事件源和订阅处理者分开

b.       降低耦合性,事件源只需要向外界暴露最少的信息,内部改变不影响外部行为

c.       降低代码复杂性,将事件不同的处理代码分散到各个订阅者内部。

2.       如何使用信息槽

a.       包含头文件, #include "sigslot.h" using namespace sigslot;

b.       在事件源类内部声名一个信号槽对象,例如:   signal1<constCString&> sltLoginFail;,其中的signal1模板表示只有一个参数.以此类推,大概有最多十几个的模板.

c.       将事件订阅者类多重继承自has_slots<>,class CLoginDlg : public CDialog,public has_slots<>。

d.       在事件订阅者类内部定义处理事件的函数, void OnLoginFail(const CString& strErrorMsg);参数一定要和前面定义的信号槽匹配。

e.       在事件订阅者初始化函数内主动订阅信号槽。 g_objHero.sltLoginFail.connect(this,&CLoginDlg::OnLoginFail);

f.        事件源事件产生时触发信号. g_objHero.sltLoginFail(szMsg);

g.       在事件订阅者的OnLoginFail函数中处理相应事件。

h.       在不需要再关心事件或订阅者退出时注销信号OnLoginFail槽,   g_objHero.sltLoginFail.disconnect(this);如果忘记会产生内存泄露

3.       例子代码

 

 

// signtest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#pragma warning(disable: 4786)
#include "sigslot.h"
#include "iostream"
#include <string>
using namespace std;

using namespace sigslot;

class CHero
{
public:
 CHero::CHero()
 {
 }

 CHero::~CHero()
 {

 }

 signal1<int> sltOnLifeChange;
 signal1<std::string> sltOnHeroName;

 signal1<std::string>* get(void)
 {
  return &sltOnHeroName;
 }

 void OnMouseClicked()
 {
  sltOnHeroName(m_heroName);
 }

 void ChangeLife(int nLife)
 {
  m_nLife=nLife;
  sltOnLifeChange(m_nLife);
 }

private:
 int m_nLife;
 std::string m_heroName;
};

class lifebar : public has_slots<>
{
// protected:
public:
 void OnLifeChange(int herolife)
 {
  cout<<"lifebar refresh hero life "<<herolife<<"/n";
 }

 void OnSetHeroName(const std::string name)
 {
  cout<<name<<"/n";
 }

 
};

///主角面板
class heropane : public has_slots<>
{
public:
 void OnLifeChange(int herolife)
 {
  cout<<"heropane refresh hero life "<<herolife<<"/n";
 }
};


int main(int argc, char* argv[])
{
 CHero hero;
 lifebar bar;
 heropane pane;

 hero.sltOnLifeChange.connect(&bar,&lifebar::OnLifeChange);
 hero.sltOnLifeChange.connect(&pane,&heropane::OnLifeChange);
 hero.get()->connect(&bar,&lifebar::OnSetHeroName);

 ///触发信号
 hero.ChangeLife(10);
 hero.OnMouseClicked();

 hero.sltOnLifeChange.disconnect(&bar);
 hero.sltOnLifeChange.disconnect(&pane);
 hero.sltOnHeroName.disconnect(&bar);
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值