最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ Boost.Signals2信號(hào)/槽概念

 更新時(shí)間:2022年12月05日 11:04:28   作者:無(wú)水先生  
Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)

一、關(guān)于Boost.Signals2

Boost.Signals2 實(shí)現(xiàn)了信號(hào)/槽的概念。一個(gè)或多個(gè)函數(shù)(稱(chēng)為槽)與可以發(fā)出信號(hào)的對(duì)象相關(guān)聯(lián)。每次發(fā)出信號(hào)時(shí),都會(huì)調(diào)用鏈接的函數(shù)。

信號(hào)/槽概念在開(kāi)發(fā)具有圖形用戶界面的應(yīng)用程序時(shí)非常有用。可以對(duì)按鈕進(jìn)行建模,以便在用戶單擊它們時(shí)發(fā)出信號(hào)。它們可以支持指向許多函數(shù)的鏈接以處理用戶輸入。這樣就可以靈活地處理事件。

std::function 也可用于事件處理。 std::function 和 Boost.Signals2 之間的一個(gè)重要區(qū)別是 Boost.Signals2 可以將多個(gè)事件處理程序與單個(gè)事件相關(guān)聯(lián)。因此,Boost.Signals2更適合支持事件驅(qū)動(dòng)開(kāi)發(fā),應(yīng)該是任何需要處理事件的首選。

Boost.Signals2 繼承了庫(kù) Boost.Signals,后者已被棄用且本書(shū)未討論。

Table of Contents

Signals

Connections

Multithreading

二、關(guān)于Signals庫(kù)

Boost.Signals2 提供類(lèi) boost::signals2::signal,可用于創(chuàng)建信號(hào)。此類(lèi)在 boost/signals2/signal.hpp 中定義。或者,您可以使用頭文件 boost/signals2.hpp,這是一個(gè)主頭文件,定義了 Boost.Signals2 中可用的所有類(lèi)和函數(shù)。

Boost.Signals2 定義了 boost::signals2::signal 和其他類(lèi),以及命名空間 boost::signals2 中的所有函數(shù)。

示例 67.1。 “你好世界!”使用 boost::signals2::signal

#include <boost/signals2.hpp>
#include <iostream>
using namespace boost::signals2;
int main()
{
  signal<void()> s;
  s.connect([]{ std::cout << "Hello, world!\n"; });
  s();
}

boost::signals2::signal 是一個(gè)類(lèi)模板,它期望將用作事件處理程序的函數(shù)的簽名作為模板參數(shù)。在示例 67.1 中,只有簽名為 void() 的函數(shù)才能與信號(hào)相關(guān)聯(lián)。

lambda 函數(shù)通過(guò) connect() 與信號(hào) s 相關(guān)聯(lián)。因?yàn)?lambda 函數(shù)符合所需的簽名 void(),所以關(guān)聯(lián)已成功建立。每當(dāng)觸發(fā)信號(hào) s 時(shí),都會(huì)調(diào)用 lambda 函數(shù)。

信號(hào)是通過(guò)像調(diào)用常規(guī)函數(shù)一樣調(diào)用 s 來(lái)觸發(fā)的。此函數(shù)的簽名與作為模板參數(shù)傳遞的簽名匹配。括號(hào)是空的,因?yàn)?void() 不需要任何參數(shù)。調(diào)用 s 會(huì)產(chǎn)生一個(gè)觸發(fā)器,而該觸發(fā)器又會(huì)執(zhí)行之前與 connect() 相關(guān)聯(lián)的 lambda 函數(shù)。

示例 67.1 也可以使用 std::function 實(shí)現(xiàn),如示例 67.2 所示。

示例 67.2。 “你好世界!”使用 std::function

#include <functional>
#include <iostream>
int main()
{
  std::function<void()> f;
  f = []{ std::cout << "Hello, world!\n"; };
  f();
}

在示例 67.2 中,調(diào)用 f 時(shí)也會(huì)執(zhí)行 lambda 函數(shù)。雖然 std::function 只能用于類(lèi)似示例 67.2 的場(chǎng)景,但 Boost.Signals2 提供了更多種類(lèi)。例如,它可以將多個(gè)函數(shù)與特定信號(hào)相關(guān)聯(lián)(參見(jiàn)示例 67.3)。

示例 67.3。帶有 boost::signals2::signal 的多個(gè)事件處理程序

#include <boost/signals2.hpp>
#include <iostream>
using namespace boost::signals2;
int main()
{
  signal<void()> s;
  s.connect([]{ std::cout << "Hello"; });
  s.connect([]{ std::cout << ", world!\n"; });
  s();
}

boost::signals2::signal 允許您通過(guò)重復(fù)調(diào)用 connect() 將多個(gè)函數(shù)分配給特定信號(hào)。每當(dāng)觸發(fā)信號(hào)時(shí),函數(shù)都會(huì)按照它們與 connect() 關(guān)聯(lián)的順序執(zhí)行。

順序也可以在 connect() 的重載版本的幫助下明確定義,它需要一個(gè) int 類(lèi)型的值作為附加參數(shù)(示例 67.4)。

示例 67.4。具有明確順序的事件處理程序

#include <boost/signals2.hpp>
#include <iostream>
using namespace boost::signals2;
int main()
{
  signal<void()> s;
  s.connect(1, []{ std::cout << ", world!\n"; });
  s.connect(0, []{ std::cout << "Hello"; });
  s();
}

與前面的示例一樣,示例 67.4 顯示 Hello, world!。

要從信號(hào)中釋放關(guān)聯(lián)函數(shù),請(qǐng)調(diào)用 disconnect()。

示例 67.5。斷開(kāi)事件處理程序與 boost::signals2::signal 的連接

#include <boost/signals2.hpp>
#include <iostream>
using namespace boost::signals2;
void hello() { std::cout << "Hello"; }
void world() { std::cout << ", world!\n"; }
int main()
{
  signal<void()> s;
  s.connect(hello);
  s.connect(world);
  s.disconnect(world);
  s();
}

Example 67.5 

示例 67.5 僅打印 Hello,因?yàn)榕c world() 的關(guān)聯(lián)在信號(hào)被觸發(fā)之前已釋放。

除了 connect() 和 disconnect() 之外,boost::signals2::signal 還提供了幾個(gè)成員函數(shù)(參見(jiàn)示例 67.6)。

示例 67.6。 boost::signals2::signal 的附加成員函數(shù)

#include <boost/signals2.hpp>
#include <iostream>
using namespace boost::signals2;
int main()
{
  signal<void()> s;
  s.connect([]{ std::cout << "Hello"; });
  s.connect([]{ std::cout << ", world!"; });
  std::cout << s.num_slots() << '\n';
  if (!s.empty())
    s();
  s.disconnect_all_slots();
}

num_slots() 返回關(guān)聯(lián)函數(shù)的數(shù)量。如果沒(méi)有函數(shù)關(guān)聯(lián),num_slots() 返回 0。empty() 告訴您事件處理程序是否已連接。而 disconnect_all_slots() 的作用正如它的名字所說(shuō):它釋放所有現(xiàn)有的關(guān)聯(lián)。

示例 67.7。處理事件處理程序的返回值

#include <boost/signals2.hpp>
#include <iostream>
using namespace boost::signals2;
int main()
{
  signal<int()> s;
  s.connect([]{ return 1; });
  s.connect([]{ return 2; });
  std::cout << *s() << '\n';
}

在示例 67.7 中,兩個(gè) lambda 函數(shù)與信號(hào)關(guān)聯(lián)。第一個(gè) lambda 函數(shù)返回 1,第二個(gè)返回 2。

示例 67.7 將 2 寫(xiě)入標(biāo)準(zhǔn)輸出。 s 正確接受了兩個(gè)返回值,但除了最后一個(gè)之外的所有返回值都被忽略了。默認(rèn)情況下,只返回所有關(guān)聯(lián)函數(shù)的最后一個(gè)返回值。

請(qǐng)注意,s() 不會(huì)直接返回上次調(diào)用的函數(shù)的結(jié)果。返回類(lèi)型為 boost::optional 的對(duì)象,取消引用時(shí)返回?cái)?shù)字 2。觸發(fā)與任何函數(shù)無(wú)關(guān)的信號(hào)不會(huì)產(chǎn)生任何返回值。因此,在這種情況下,boost::optional 允許 Boost.Signals2 返回一個(gè)空對(duì)象。 boost::optional 在第 21 章中介紹。

可以自定義信號(hào),以便相應(yīng)地處理各個(gè)返回值。為此,必須將組合器作為第二個(gè)模板參數(shù)傳遞給 boost::signals2::signal。

示例 67.8。使用用戶定義的組合器查找最小返回值

#include <boost/signals2.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace boost::signals2;
template <typename T>
struct min_element
{
  typedef T result_type;
  template <typename InputIterator>
  T operator()(InputIterator first, InputIterator last) const
  {
    std::vector<T> v(first, last);
    return *std::min_element(v.begin(), v.end());
  }
};
int main()
{
  signal<int(), min_element<int>> s;
  s.connect([]{ return 1; });
  s.connect([]{ return 2; });
  std::cout << s() << '\n';
}

組合器是一個(gè)具有重載的 operator() 的類(lèi)。該運(yùn)算符使用兩個(gè)迭代器自動(dòng)調(diào)用,這兩個(gè)迭代器用于訪問(wèn)與特定信號(hào)關(guān)聯(lián)的函數(shù)。當(dāng)?shù)鞅蝗∠脮r(shí),函數(shù)被調(diào)用并且它們的返回值在組合器中變得可用。然后可以使用標(biāo)準(zhǔn)庫(kù)中的常用算法,例如 std::min_element() 來(lái)計(jì)算并返回最小值(參見(jiàn)示例 67.8)。

boost::signals2::signal 使用 boost::signals2::optional_last_value 作為默認(rèn)組合器。此組合器返回 boost::optional 類(lèi)型的對(duì)象。用戶可以定義一個(gè)具有任何類(lèi)型返回值的組合器。例如,示例 67.8 中的組合器 min_element 返回作為模板參數(shù)傳遞給 min_element 的類(lèi)型。

無(wú)法將諸如 std::min_element() 之類(lèi)的算法作為模板參數(shù)直接傳遞給 boost::signals2::signal。 boost::signals2::signal 期望組合器定義一個(gè)名為 result_type 的類(lèi)型,它表示 operator() 返回值的類(lèi)型。由于這個(gè)類(lèi)型沒(méi)有被標(biāo)準(zhǔn)算法定義,所以編譯器會(huì)報(bào)錯(cuò)。

請(qǐng)注意,不可能將迭代器 first 和 last 直接傳遞給 std::min_element() ,因?yàn)樵撍惴ㄐ枰跋虻?,而組合器使用輸入迭代器。這就是為什么在使用 std::min_element() 確定最小值之前使用向量存儲(chǔ)所有返回值的原因。

示例 67.9 修改組合器以將所有返回值存儲(chǔ)在容器中,而不是評(píng)估它們。它將所有返回值存儲(chǔ)在一個(gè)向量中,然后由 s() 返回該向量。

示例 67.9。使用用戶定義的組合器接收所有返回值

#include <boost/signals2.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace boost::signals2;
template <typename T>
struct return_all
{
  typedef T result_type;
  template <typename InputIterator>
  T operator()(InputIterator first, InputIterator last) const
  {
    return T(first, last);
  }
};
int main()
{
  signal<int(), return_all<std::vector<int>>> s;
  s.connect([]{ return 1; });
  s.connect([]{ return 2; });
  std::vector<int> v = s();
  std::cout << *std::min_element(v.begin(), v.end()) << '\n';
}

練習(xí)

創(chuàng)建一個(gè)帶有課程按鈕的程序。該類(lèi)應(yīng)代表圖形用戶界面中的按鈕。添加成員函數(shù) add_handler() 和 remove_handler() ,它們都希望傳遞一個(gè)函數(shù)。如果調(diào)用另一個(gè)名為 click() 的成員函數(shù),則應(yīng)依次調(diào)用已注冊(cè)的處理程序。通過(guò)注冊(cè)一個(gè)將消息寫(xiě)入標(biāo)準(zhǔn)輸出的處理程序來(lái)實(shí)例化按鈕并測(cè)試該類(lèi)。調(diào)用 click() 來(lái)模擬鼠標(biāo)點(diǎn)擊按鈕。

到此這篇關(guān)于C++ Boost.Signals2信號(hào)/槽概念的文章就介紹到這了,更多相關(guān)C++ Boost Signals2內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)任意進(jìn)制的代碼詳解

    C語(yǔ)言實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)任意進(jìn)制的代碼詳解

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)任意進(jìn)制,運(yùn)用一個(gè)數(shù)組,通過(guò)數(shù)字每次取任意進(jìn)制模,存在數(shù)組中, 再通過(guò)倒取數(shù)組中的數(shù)值,來(lái)實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換,如果遇到十六進(jìn)制,利用ASCII碼值  數(shù)字字符和大寫(xiě)字母 相差55的特性來(lái)解決,文中有詳細(xì)代碼示例,需要的朋友可以參考下
    2024-05-05
  • C/C++語(yǔ)言中全局變量重復(fù)定義問(wèn)題的解決方法

    C/C++語(yǔ)言中全局變量重復(fù)定義問(wèn)題的解決方法

    這篇文章主要給大家介紹了關(guān)于C/C++語(yǔ)言中全局變量重復(fù)定義問(wèn)題的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • C語(yǔ)言輸出孿生素?cái)?shù)的實(shí)現(xiàn)示例

    C語(yǔ)言輸出孿生素?cái)?shù)的實(shí)現(xiàn)示例

    本文主要介紹了C語(yǔ)言輸出孿生素?cái)?shù)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Matlab實(shí)現(xiàn)繪制有氣泡感的網(wǎng)絡(luò)圖

    Matlab實(shí)現(xiàn)繪制有氣泡感的網(wǎng)絡(luò)圖

    這篇文章主要介紹了如何利用Matlab實(shí)現(xiàn)繪制有氣泡感的網(wǎng)絡(luò)圖,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Matlab有一定的幫助,需要的可以參考一下
    2023-02-02
  • C++程序中main(int argc, char *argv[])函數(shù)的參數(shù)意義

    C++程序中main(int argc, char *argv[])函數(shù)的參數(shù)意義

    這篇文章主要介紹了C++程序中main(int argc, char *argv[])函數(shù)的參數(shù)意義,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)系列之樹(shù)的概念結(jié)構(gòu)和常見(jiàn)表示方法

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)系列之樹(shù)的概念結(jié)構(gòu)和常見(jiàn)表示方法

    本章將正式開(kāi)啟數(shù)據(jù)結(jié)構(gòu)中?“樹(shù)”?部分的講解,本章將介紹樹(shù)的概念和結(jié)構(gòu),以及樹(shù)的表示方法,感興趣的朋友進(jìn)來(lái)看看吧
    2022-02-02
  • C++多線程強(qiáng)制終止詳細(xì)

    C++多線程強(qiáng)制終止詳細(xì)

    這篇文章主要介紹了C++多線程強(qiáng)制終止, 實(shí)際上,沒(méi)有任何語(yǔ)言或操作系統(tǒng)可以為你提供異步突然終止線程的便利,且不會(huì)警告你不要使用它們。但是下面我們?cè)賮?lái)簡(jiǎn)單看看相關(guān)內(nèi)容吧
    2021-09-09
  • C語(yǔ)言算法練習(xí)之佩奇借書(shū)

    C語(yǔ)言算法練習(xí)之佩奇借書(shū)

    這篇文章主要該大家分享C語(yǔ)言佩奇借書(shū)的練習(xí),文章主要通過(guò)描述佩奇借書(shū)的問(wèn)題然后確定程序框架將結(jié)果運(yùn)算出來(lái),下面來(lái)看詳細(xì)內(nèi)容吧,需要的朋友可以參考一下
    2022-03-03
  • Visual Studio 2019 Professional 激活方法詳解

    Visual Studio 2019 Professional 激活方法詳解

    這篇文章主要介紹了Visual Studio 2019 Professional 激活方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 詳解C++中const_cast與reinterpret_cast運(yùn)算符的用法

    詳解C++中const_cast與reinterpret_cast運(yùn)算符的用法

    這篇文章主要介紹了C++中const_cast與reinterpret_cast運(yùn)算符的用法,經(jīng)常被用于表達(dá)式中的類(lèi)型轉(zhuǎn)換,需要的朋友可以參考下
    2016-01-01

最新評(píng)論

咸丰县| 偏关县| 大足县| 平利县| 灵山县| 华坪县| 祁东县| 雷波县| 禹城市| 连城县| 青岛市| 兴安盟| 阿拉善右旗| 谷城县| 醴陵市| 丹东市| 安多县| 乐陵市| 余江县| 张家口市| 乌鲁木齐市| 图片| 社旗县| 大港区| 平顺县| 搜索| 瑞昌市| 平安县| 隆化县| 萨迦县| 南乐县| 安龙县| 墨竹工卡县| 福贡县| 柏乡县| 晋州市| 新和县| 天全县| 建平县| 孝昌县| 明星|