日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解信号槽(二)

發布時間:2025/4/16 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解信号槽(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多對多

下一個問題是,我們能夠在點擊一次重新載入按鈕之后做多個操作嗎?也就是讓信號和槽實現多對多的關系?

實際上,我們只需要利用一個普通的鏈表,就可以輕松實現這個功能了。比如,如下的實現:

class MultiAction : public AbstractAction// ...an action that is composed of zero or more other actions;// executing it is really executing each of the sub-actions { public:// ...virtual void execute(); private:std::vector<AbstractAction*> actionList_;// ...or any reasonable collection machinery };void MultiAction::execute() {// call execute() on each action in actionList_std::for_each( actionList_.begin(),actionList_.end(),boost::bind(&AbstractAction::execute, _1) ); }

這就是其中的一種實現。不要覺得這種實現看上去沒什么水平,實際上我們發現這就是一種相當簡潔的方法。同時,不要糾結于我們代碼中的 std:: 和 boost:: 這些命名空間,你完全可以用另外的類,強調一下,這只是一種可能的實現。現在,我們的一個動作可以連接多個 button 了,當然,也可以是別的 Action 的使用者。現在,我們有了一個多對多的機制。通過將 AbstractAction* 替換成 boost::shared_ptr<AbstractAction>,可以解決 AbstractAction 的歸屬問題,同時保持原有的多對多的關系。

這會有很多的類!

如果你在實際項目中使用上面的機制,很多就會發現,我們必須為每一個 action 定義一個類,這將不可避免地引起類爆炸。至今為止,我們前面所說的所有實現都存在這個問題。不過,我們之后將著重討論這個問題,現在先不要糾結在這里啦!

特化!特化!

當我們開始工作的時候,我們通過將每一個 button 賦予不同的 action,實現 Button 類的重用。這實際是一種特化。然而,我們的問題是,action 的特化被放在了固定的類層次中,在這里就是這些 Button 類。這意味著,我們的 action 很難被更大規模的重用,因為每一個 action 實際都是與 Button 類綁定的。那么,我們換個思路,能不能將這種特化放到信號與槽連接的時候進行呢?這樣,action 和 button 這兩者都不必進行特化了。

函數對象

將一個類的函數進行一定曾度的封裝,這個思想相當有用。實際上,我們的 Action 類的存在,就是將 execute() 這個函數進行封裝,其他別無用處。這在 C++ 里面還是比較普遍的,很多時候我們用 ++ 的特性重新封裝函數,讓類的行為看起來就像函數一樣。例如,我們重載 operator() 運算符,就可以讓類看起來很像一個函數:

class AbstractAction { public:virtual void operator()() = 0; };// using an action (given AbstractAction& action) action();

這樣,我們的類看起來很像函數。前面代碼中的 for_each 也得做相應的改變:

// previously std::for_each( actionList_.begin(),actionList_.end(),boost::bind(&AbstractAction::execute, _1) ); // now std::for_each( actionList_.begin(),actionList_.end(),boost::bind(&AbstractAction::operator(), _1) );

現在,我們的 Button::clicked() 函數的實現有了更多的選擇:

// previously action_->execute();// option 1: use the dereferenced pointer like a function (*action_)();// option 2: call the function by its new name action_->operator()();

看起來很麻煩,值得這樣做嗎?

下面我們來試著解釋一下信號和槽的目的。看上去,重寫 operator() 運算符有些過分,并不值得我們去這么做。但是,要知道,在某些問題上,你提供的可用的解決方案越多,越有利于我們編寫更簡潔的代碼。通過對一些類進行規范,就像我們要讓函數對象看起來更像函數,我們可以讓它們在某些環境下更適合重用。在使用模板編程,或者是 Boost.Function,bind 或者是模板元編程的情形下,這一點尤為重要。

這是對無需更多特化建立信號槽連接重要性的部分回答。模板就提供了這樣一種機制,讓添加了特化參數的代碼并不那么難地被特化,正如我們的函數對象那樣。而模板的特化對于使用者而言是透明的。

松耦合

現在,讓我們回顧一下我們之前的種種做法。

我們執著地尋求一種能夠在同一個地方調用不同函數的方法,這實際上是 C++ 內置的功能之一,通過 virtual 關鍵字,當然,我們也可以使用函數指針實現。當我們需要調用的函數沒有一個合適的簽名,我們將它包裝成一個類。我們已經演示了如何在同一地方調用多個函數,至少我們知道有這么一種方法(但這并不是在編譯期完成的)。我們實現了讓“信號發送”能夠被若干個不同的“槽”監聽。

不過,我們的系統的確沒有什么非常與眾不同的地方。我們來仔細審核一下我們的系統,它真正不同的是:

  • 定義了兩個不同的術語:“信號”和“槽”;
  • 在一個調用點(信號)與零個或者多個回調(槽)相連;
  • 連接的焦點從提供者處移開,更多地轉向消費者(也就是說,Button 并不需要知道如何做是正確的,而是由回調函數去告知 Button,你需要調用我)。

但是,這樣的系統還遠達不到松耦合的關系。Button 類并不需要知道 Page 類。松耦合意味著更少的依賴;依賴越少,組件的可重用性也就越高。

當然,肯定需要有組件同時知道 Button 和 Page,從而完成對它們的連接。現在,我們的連接實際是用代碼描述的,如果我們不用代碼,而用數據描述連接呢?這么一來,我們就有了松耦合的類,從而提高二者的可重用性。

新的連接模式

什么樣的連接模式才算是非代碼描述呢?假如僅僅只有一種信號槽的簽名,例如 void (*signature)(),這并不能實現。使用散列表,將信號的名字映射到匹配的連接函數,將槽的名字映射到匹配的函數指針,這樣的一對字符串即可建立一個連接。

然而,這種實現其實包含一些“握手”協議。我們的確希望具有多種信號槽的簽名。在信號槽的簡短回答中我們提到,信號可以攜帶附加信息。這要求信號具有參數。我們并沒有處理成員函數與非成員函數的不同,這又是一種潛在的函數簽名的不同。我們還沒有決定,我們是直接將信號連接到槽函數上,還是連接到一個包裝器上。如果是包裝器,這個包裝器需要已經存在呢,還是我們在需要時自動創建呢?雖然底層思想很簡單,但是,真正的實現還需要很好的努力才行。似乎通過類名能夠創建對象是一種不錯的想法,這取決于你的實現方式,有時候甚至取決于你有沒有能力做出這種實現。將信號和槽放入散列表需要一種注冊機制。一旦有了這么一種系統,前面所說的“有太多類了”的問題就得以解決了。你所需要做的就是維護這個散列表的鍵值,并且在需要的時候實例化類。

給信號槽添加這樣的能力將比我們前面所做的所有工作都困難得多。在由鍵值進行連接時,多數實現都會選擇放棄編譯期類型安全檢查,以滿足信號和槽的兼容。這樣的系統代價更高,但是其應用也遠遠高于自動信號槽連接。這樣的系統允許實例化外部的類,比如 Button 以及它的連接。所以,這樣的系統有很強大的能力,它能夠完成一個類的裝配、連接,并最終完成實例化操作,比如直接從資源描述文件中導出的一個對話框。既然它能夠憑借名字使函數可用,這就是一種腳本能力。如果你需要上面所說的種種特性,那么,完成這么一套系統絕對是值得的,你的信號槽系統也會從中受益,由數據去完成信號槽的連接。

對于不需要這種能力的實現則會忽略這部分特性。從這點看,這種實現就是“輕量級”的。對于一個需要這些特性的庫而言,完整地實現出來就是一個輕量級實現。這也是區別這些實現的方法之一。



本文轉自 FinderCheng 51CTO博客,原文鏈接:?

http://blog.51cto.com/devbean/424778

總結

以上是生活随笔為你收集整理的深入理解信号槽(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 九热这里只有精品 | 成年免费视频黄网站在线观看 | 国产精品99久久久久久www | ass亚洲熟妇毛耸耸pics | 精品无码久久久久国产 | 黄色网址在线视频 | 日韩欧美色 | 99热精品在线 | 国产91在线亚洲 | 一本色道久久亚洲综合精品蜜桃 | 爱爱中文字幕 | av青青草原 | 女女h百合无遮涩涩漫画软件 | 激情六月综合 | 亚洲va欧美va国产综合久久 | 国产91久久精品一区二区 | 羞羞羞网站 | 永久免费毛片 | 超碰网站在线 | 国内福利视频 | 手机在线观看av片 | 大学生av | 久久精品人人做人人爽 | 你懂的国产在线 | av天天堂 | 日韩影视一区 | 久久精品国产欧美亚洲人人爽 | 国产香蕉一区二区三区 | 日本一区二区精品 | 免费日韩在线 | 激情久久av一区av二区av三区 | 色播五月激情五月 | 久久伊人精品 | 高清中文字幕 | 国产乱子伦视频一区二区三区 | av国语| 超碰干 | 久久三级网站 | 日韩欧美成人一区 | 高清视频一区二区 | 国产视频在线观看免费 | 婷久久| 男男成人高潮片免费网站 | 色偷偷成人 | 婷婷激情电影 | 国产精品毛片一区视频播 | 色老板精品凹凸在线视频观看 | 四虎影视免费看 | 中文字幕一区二区三区av | 久久成人国产精品入口 | av免费不卡| 欧美美女喷水 | 北条麻妃一区二区三区在线观看 | 偷偷操视频 | 久久大伊人 | 欧美性大战久久久 | 成人1区2区 | 日本xxxx高清 | 日韩乱码在线观看 | 精品人妻一区二区三区日产 | 亚洲天天视频 | 私人av| 国产一国产精品一级毛片 | www.亚洲天堂 | 电影桑叶2在线播放完整版 222aaa | wwww黄色片 | 国产美女精品久久久 | 女人裸体免费网站 | 亚洲一区二区三区麻豆 | 亚洲成人一 | 在线观看深夜视频 | 青草精品视频 | 亚洲成人激情在线 | 最新三级网站 | 欧美久久99| 日韩在线中文字幕视频 | 亚洲福利 | 欧美疯狂做受 | 中国国语农村大片 | 成人黄色激情视频 | 色综合999 | 亚洲日本在线观看 | 中文字幕+乱码+中文字幕一区 | 一区成人| 福利所第一导航 | 姑娘第5集高清在线观看 | 成年人黄色网址 | 无码人妻一区二区三区在线 | 自拍偷拍欧美日韩 | 久久精品国产欧美亚洲人人爽 | cao死你| 国产一级大片在线观看 | 国产传媒在线视频 | 三级欧美视频 | 在线视频欧美日韩 | 久久无码专区国产精品s | 99在线观看| 99re99热| 黑人vs亚洲人在线播放 |