信号槽作用:.
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;
}