C++信息槽 信号槽

信号槽作用:.   

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

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

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

使用信息槽

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

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

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

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

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

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

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

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

 

       例子代码

// 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;
}

你可能感兴趣的:(C++信息槽 信号槽)