程序开发基础学习四(boost::signal2 函数学习)
2011-07-18 18:06
537 查看
在游戏编程中,新的策划需求总是在迭代不停。。。。。。,对于游戏程序员肯定深有感触吧,遇到这种情况咱只能小小的抱怨下,活还得干。尤其是遇到耦合到很多类的时候,要是直接实现不加抽象的话,那咱的代码就要被拆的七零八落,并且在代码维护性和程序健壮性上问题很大。前面说到的问题其实就是常听到的代码耦合,说白了就是在原有的代码上插上一段代码。而signal就能很好的解决这种问题。这样不仅可以让咱的代码优美,而且修改的时候也很方便。好的,按照惯例先模拟一下signal的实现方法。看清它的真面目,也就不用害怕了。1、signal模拟程序#include "stdafx.h"
#include <iostream>
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "boost/signals2.hpp"
using namespace std;
using namespace boost;
class Buttion
{
public:
void connect(void (*f)(int, int));
void OnBtnClick();
private:
void (*fuc_)(int, int);
};
void Buttion::connect(void (*f)(int, int))
{
fuc_ = f;
}
void Buttion::OnBtnClick()
{
fuc_(10, 20);
}
void PrintCodeline(int x, int y)
{
cout<<"x:"<<x<<",y:"<<y<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Buttion btn;
btn.connect(&PrintCodeline);
btn.OnBtnClick();
getchar();
return 0;
}
看见了吗?其实就是传递个函数指针,不过signal用的是template而已,并且里面还有一些保护机制。在下面的程序会提到。2、signal函数实现#include "stdafx.h"
#include <iostream>
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "boost/signals2.hpp"
using namespace std;
using namespace boost;
class Buttion
{
typedef signals2::signal<void (int ,int)> OnClick;
public:
typedef OnClick::slot_type OnSlottype;
signals2::connection connect(const OnSlottype& type);
void OnBtnClick();
private:
OnClick onclick_;
signals2::connection connect_;
};
signals2::connection Buttion::connect(const OnSlottype& type)
{
return connect_ = onclick_.connect(type);
}
void Buttion::OnBtnClick()
{
onclick_(10, 20);
}
void PrintCodeline(int x, int y)
{
cout<<"x:"<<x<<",y:"<<y<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Buttion btn;
btn.connect(&PrintCodeline);
btn.OnBtnClick();
getchar();
return 0;
} 重点有两个方面,一个是OnSlottype,其实就相当于上一个列子中的函数指针,在一个要问为什么要返回成员变量connect_,一个原因是通过它的返回值可以知道是否connect成功,另一个在用完之后调用disconnect方法,释放connect_变量。
3、类之间相互调用// mercurial.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "boost/ref.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/signals2.hpp"
using namespace std;
using namespace boost;
class Document
{
typedef signals2::signal<void (void)> signal_t;
public:
Document(){}
signals2::connection connect(const signal_t::slot_type &subscriper)
{
return sig_.connect(subscriper);
}
void Append(const char* text)
{
text_ += text;
sig_();
}
string GetText()
{
return text_;
}
private:
signal_t sig_;
string text_;
};
class TextView
{
public:
TextView(Document* doc):doc_(doc)
{
connect_ = doc_->connect(bind(&TextView::Refresh, this));
}
~TextView()
{
connect_.disconnect();
}
void Refresh()
{
cout<<doc_->GetText()<<endl;
}
private:
signals2::connection connect_;
Document* doc_;
};
class HexView
{
public:
HexView(Document* doc):doc_(doc)
{
connect_ = doc_->connect(bind(&HexView::Refresh, this));
}
~HexView()
{
connect_.disconnect();
}
void Refresh()
{
string str = doc_->GetText();
for (size_t i = 0; i < str.size(); ++i)
{
cout<<(int)str[i];
}
cout<<endl;
}
private:
Document* doc_;
signals2::connection connect_;
};
int _tmain(int argc, char* argv[])
{
Document *doc = new Document();
TextView text(doc);
HexView hex(doc);
doc->Append(argc == 2 ? argv[1] : "Hello,Word.");
delete doc;
getchar();
return 0;
}
这个程序模仿boost给出的示例写的,要注意的是在TextView和HexView两个构造函数传递的是Document的指针,之前我自己写的时候传递的是Document的复制,但是编译不过。signal自己有不允许复制的机制。这就很强大了,本来是粗心造成的一个问题(复制的话,就不能改变传递的参数了),signal在编译的时候就能检测出问题了。有点只能的感觉了。再一个在main函数里我只申明TextView和HexView两个对象。调用下Document的一个函数,就将TextView和HexView的函数都别调用了。这不就是传说中的“杀人”于无形中,这样很大程度上封装了函数,简化了表现层的复杂度。
#include <iostream>
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "boost/signals2.hpp"
using namespace std;
using namespace boost;
class Buttion
{
public:
void connect(void (*f)(int, int));
void OnBtnClick();
private:
void (*fuc_)(int, int);
};
void Buttion::connect(void (*f)(int, int))
{
fuc_ = f;
}
void Buttion::OnBtnClick()
{
fuc_(10, 20);
}
void PrintCodeline(int x, int y)
{
cout<<"x:"<<x<<",y:"<<y<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Buttion btn;
btn.connect(&PrintCodeline);
btn.OnBtnClick();
getchar();
return 0;
}
看见了吗?其实就是传递个函数指针,不过signal用的是template而已,并且里面还有一些保护机制。在下面的程序会提到。2、signal函数实现#include "stdafx.h"
#include <iostream>
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "boost/signals2.hpp"
using namespace std;
using namespace boost;
class Buttion
{
typedef signals2::signal<void (int ,int)> OnClick;
public:
typedef OnClick::slot_type OnSlottype;
signals2::connection connect(const OnSlottype& type);
void OnBtnClick();
private:
OnClick onclick_;
signals2::connection connect_;
};
signals2::connection Buttion::connect(const OnSlottype& type)
{
return connect_ = onclick_.connect(type);
}
void Buttion::OnBtnClick()
{
onclick_(10, 20);
}
void PrintCodeline(int x, int y)
{
cout<<"x:"<<x<<",y:"<<y<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Buttion btn;
btn.connect(&PrintCodeline);
btn.OnBtnClick();
getchar();
return 0;
} 重点有两个方面,一个是OnSlottype,其实就相当于上一个列子中的函数指针,在一个要问为什么要返回成员变量connect_,一个原因是通过它的返回值可以知道是否connect成功,另一个在用完之后调用disconnect方法,释放connect_变量。
3、类之间相互调用// mercurial.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "boost/ref.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/signals2.hpp"
using namespace std;
using namespace boost;
class Document
{
typedef signals2::signal<void (void)> signal_t;
public:
Document(){}
signals2::connection connect(const signal_t::slot_type &subscriper)
{
return sig_.connect(subscriper);
}
void Append(const char* text)
{
text_ += text;
sig_();
}
string GetText()
{
return text_;
}
private:
signal_t sig_;
string text_;
};
class TextView
{
public:
TextView(Document* doc):doc_(doc)
{
connect_ = doc_->connect(bind(&TextView::Refresh, this));
}
~TextView()
{
connect_.disconnect();
}
void Refresh()
{
cout<<doc_->GetText()<<endl;
}
private:
signals2::connection connect_;
Document* doc_;
};
class HexView
{
public:
HexView(Document* doc):doc_(doc)
{
connect_ = doc_->connect(bind(&HexView::Refresh, this));
}
~HexView()
{
connect_.disconnect();
}
void Refresh()
{
string str = doc_->GetText();
for (size_t i = 0; i < str.size(); ++i)
{
cout<<(int)str[i];
}
cout<<endl;
}
private:
Document* doc_;
signals2::connection connect_;
};
int _tmain(int argc, char* argv[])
{
Document *doc = new Document();
TextView text(doc);
HexView hex(doc);
doc->Append(argc == 2 ? argv[1] : "Hello,Word.");
delete doc;
getchar();
return 0;
}
这个程序模仿boost给出的示例写的,要注意的是在TextView和HexView两个构造函数传递的是Document的指针,之前我自己写的时候传递的是Document的复制,但是编译不过。signal自己有不允许复制的机制。这就很强大了,本来是粗心造成的一个问题(复制的话,就不能改变传递的参数了),signal在编译的时候就能检测出问题了。有点只能的感觉了。再一个在main函数里我只申明TextView和HexView两个对象。调用下Document的一个函数,就将TextView和HexView的函数都别调用了。这不就是传说中的“杀人”于无形中,这样很大程度上封装了函数,简化了表现层的复杂度。
相关文章推荐
- 程序开发基础学习四(boost::signal2 函数学习)
- 程序开发基础学习三(boost::bind 函数学习)
- 程序开发基础学习三(boost::bind 函数学习)
- 程序开发基础学习三(boost::bind 函数学习)
- 程序开发基础学习五(json配置、解析文件,c++篇)
- Cocoa 基础学习:屏幕坏点检查程序开发实例
- 《Boost程序完全开发》跟踪学习训练一:Boost::date_time库的使用
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<Oracle_函数_触发器_游标_存储过程_视图>(三十五)
- 程序开发基础学习二(C++ Google Style 命名规则)
- 【零基础学习iOS开发】【02-C语言】10-函数
- UI基础:UI程序执行顺序(UIApplicationMain()函数),自定义视图 分类: iOS学习-UI 2015-07-02 22:09 68人阅读 评论(0) 收藏
- Jcrontab - java定时程序进阶学习-Java基础-Java-编程开发
- EA&UML日拱一卒-0基础学习微信小程序(4)- 安装开发工具
- 程序开发基础学习二(C++ Google Style 命名规则)
- 【零基础学习iOS开发】【02-C语言】11-函数的声明和定义
- 程序开发基础学习一(uml设计)
- 一个非常非常非常基础的程序,写的不好,但是一般的文件读写操作及字符处理函数都涉及到了..新手学习用的
- 【学习笔记】零基础C#窗口程序开发入门
- [学习笔记]java基础Java8SE开发环境搭建、第一个Java Hello World、Java程序的编译与执行
- 嵌入式系统学习(五)-NanoPi2基础实例开发(裸机程序按钮控制LED灯)