程序开发基础学习四(boost::signal2 函数学习)
生活随笔
收集整理的這篇文章主要介紹了
程序开发基础学习四(boost::signal2 函数学习)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ? 在游戲編程中,新的策劃需求總是在迭代不停。。。。。。,對于游戲程序員肯定深有感觸吧,遇到這種情況咱只能小小的抱怨下,活還得干。尤其是遇到耦合到很多類的時候,要是直接實現不加抽象的話,那咱的代碼就要被拆的七零八落,并且在代碼維護性和程序健壯性上問題很大。前面說到的問題其實就是常聽到的代碼耦合,說白了就是在原有的代碼上插上一段代碼。而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的函數都別調用了。這不就是傳說中的“殺人”于無形中,這樣很大程度上封裝了函數,簡化了表現層的復雜度。
轉載于:https://www.cnblogs.com/fengju/archive/2011/07/18/6174340.html
總結
以上是生活随笔為你收集整理的程序开发基础学习四(boost::signal2 函数学习)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《女管家》东方靖琪变坏了吗 结局怎么样了
- 下一篇: HDOJ 1896 Stones 解题报