欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解c++實(shí)現(xiàn)Qt信號(hào)和槽機(jī)制

 更新時(shí)間:2023年08月08日 11:47:04   作者:ccloud11  
信號(hào)和槽機(jī)制是 Qt 的核心機(jī)制,可以讓編程人員將互不相關(guān)的對(duì)象綁定在一起,實(shí)現(xiàn)對(duì)象之間的通信,本文就來深入理解c++實(shí)現(xiàn)Qt信號(hào)和槽機(jī)制,感興趣的可以了解一下

簡(jiǎn)介

信號(hào)槽機(jī)制與Windows下消息機(jī)制類似,消息機(jī)制是基于回調(diào)函數(shù),Qt中用信號(hào)與槽來代替函數(shù)指針,使程序更安全簡(jiǎn)潔。

信號(hào)和槽機(jī)制是 Qt 的核心機(jī)制,可以讓編程人員將互不相關(guān)的對(duì)象綁定在一起,實(shí)現(xiàn)對(duì)象之間的通信。

信號(hào)

當(dāng)對(duì)象改變其狀態(tài)時(shí),信號(hào)就由該對(duì)象發(fā)射 (emit) 出去,而且對(duì)象只負(fù)責(zé)發(fā)送信號(hào),它不知道另一端是誰在接收這個(gè)信號(hào)。這樣就做到了真正的信息封裝,能確保對(duì)象被當(dāng)作一個(gè)真正的軟件組件來使用。

用于接收信號(hào),而且槽只是普通的對(duì)象成員函數(shù)。一個(gè)槽并不知道是否有任何信號(hào)與自己相連接。而且對(duì)象并不了解具體的通信機(jī)制。

信號(hào)與槽的連接

所有從 QObject 或其子類 ( 例如 Qwidget ) 派生的類都能夠包含信號(hào)和槽。因?yàn)樾盘?hào)與槽的連接是通過 QObject 的 connect() 成員函數(shù)來實(shí)現(xiàn)的。

connect(sender, SIGNAL(signal), receiver, SLOT(slot));

其中 sender 與 receiver 是指向?qū)ο蟮闹羔槪琒IGNAL() 與 SLOT() 是轉(zhuǎn)換信號(hào)與槽的宏。

特點(diǎn)

1、一個(gè)信號(hào)可以連接多個(gè)槽

當(dāng)信號(hào)發(fā)射時(shí),會(huì)以不確定的順序一個(gè)接一個(gè)的調(diào)用各個(gè)槽。

2、多個(gè)信號(hào)可以連接同一個(gè)槽

即無論是哪一個(gè)信號(hào)被發(fā)射,都會(huì)調(diào)用這個(gè)槽。

3、信號(hào)直接可以相互連接

發(fā)射第一個(gè)信號(hào)時(shí),也會(huì)發(fā)射第二個(gè)信號(hào)。4、連接可以被移除

這種情況用得比較少,因?yàn)樵趯?duì)象被刪除時(shí),Qt會(huì)自動(dòng)移除與這個(gè)對(duì)象相關(guān)的所有連接。語法如下:

disconnect(sender, SIGNAL(signal), receiver, SLOT(slot));

觀察者模式

定義

觀察者模式(又被稱為發(fā)布-訂閱(Publish/Subscribe)模式,屬于行為型模式的一種,它定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)變化時(shí),會(huì)通知所有的觀察者對(duì)象,使他們能夠自動(dòng)更新自己。

觀察者模式結(jié)構(gòu)圖

在觀察者模式中有如下角色:

1、Subject:抽象主題(抽象被觀察者),抽象主題角色把所有觀察者對(duì)象保存在一個(gè)集合里,每個(gè)主題都可以有任意數(shù)量的觀察者,抽象主題提供一個(gè)接口,可以增加和刪除觀察者對(duì)象。
2、ConcreteSubject:具體主題(具體被觀察者),該角色將有關(guān)狀態(tài)存入具體觀察者對(duì)象,在具體主題的內(nèi)部狀態(tài)發(fā)生改變時(shí),給所有注冊(cè)過的觀察者發(fā)送通知。
3、Observer:抽象觀察者,是觀察者者的抽象類,它定義了一個(gè)更新接口,使得在得到主題更改通知時(shí)更新自己。
4、ConcrereObserver:具體觀察者,實(shí)現(xiàn)抽象觀察者定義的更新接口,以便在得到主題更改通知時(shí)更新自身的狀態(tài)。

實(shí)現(xiàn)簡(jiǎn)單的信號(hào)和槽

為什么要說觀察者模式呢?因?yàn)镼t的信號(hào)和槽就是基于這種設(shè)計(jì)模式來進(jìn)行設(shè)計(jì)的。通過信號(hào)和槽將對(duì)發(fā)送者信號(hào)感興趣的對(duì)象連接起來,當(dāng)發(fā)送者的信號(hào)發(fā)送的時(shí)候,就會(huì)對(duì)這個(gè)列表進(jìn)行遍歷,這種方式類似于廣播,不關(guān)心用戶是否收到,只是進(jìn)行發(fā)送而已。下面是實(shí)現(xiàn)方式。

#include <iostream>
#include <vector>
using namespace std;
//槽函數(shù)類
template <class TParam>
class SlotBase
{
public:
    virtual void slotFuntion(TParam) = 0;
    virtual ~SlotBase() = default;
};
template <class TReceiver,class TParam>
class Slot:public SlotBase<TParam>
{
private:
    TReceiver *m_preveiver;
    void (TReceiver::*m_func)(TParam);
public:
    Slot(TReceiver * reveiver,void(TReceiver::*func)(TParam))
    {
        m_preveiver = reveiver;
        m_func = func;
    }
    void slotFuntion(TParam param) override
    {
        (m_preveiver->*m_func)(param);
    }
};
//信號(hào)類
template <class TParam>
class Signal
{
private:
    std::vector<SlotBase<TParam> *> signal_vector;
public:
    template <class TReceiver>
    void addSlot(TReceiver *reveiver,void(TReceiver::*func)(TParam))
    {
        signal_vector.push_back(new Slot(reveiver,func));
    }
    void operator()(TParam param)
    {
        for(SlotBase<TParam> *p:signal_vector)
        {
            p->slotFuntion(param);
        }
    }
};
//兩個(gè)測(cè)試的接受信號(hào)類
class Receiver1
{
public:
    void func1(int param)
    {
        std::cout<<"這是Receiver1類中方法,參數(shù)為"<<param<<endl;
    }
};
class Receiver2
{
public:
    void func2(int param)
    {
        std::cout<<"這是Receiver2類中方法,參數(shù)為"<<param<<endl;
    }
};
class SendObj
{
public:
    Signal<int> valueChanged;
public:
    void testSend(int value)
    {
        valueChanged(value);
    }
};
#define connect(send,signal,reveiver,slot) send->signal.addSlot(reveiver,slot)
int main()
{
    SendObj *send=new SendObj;
    Receiver1 *r1 = new Receiver1;
    Receiver2 *r2 = new Receiver2;
    connect(send,valueChanged,r1,&Receiver1::func1);
    connect(send,valueChanged,r2,&Receiver2::func2);
    send->testSend(100);
    return 0;
}

 到此這篇關(guān)于深入理解c++實(shí)現(xiàn)Qt信號(hào)和槽機(jī)制的文章就介紹到這了,更多相關(guān)c++實(shí)現(xiàn)Qt信號(hào)和槽機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言分裝實(shí)現(xiàn)三子棋游戲詳解

    C語言分裝實(shí)現(xiàn)三子棋游戲詳解

    這篇文章主要為大家詳細(xì)介紹了C語言分裝實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C/C++實(shí)現(xiàn)磁盤相關(guān)操作的示例代碼

    C/C++實(shí)現(xiàn)磁盤相關(guān)操作的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C/C++如何實(shí)現(xiàn)磁盤相關(guān)操作,例如遍歷磁盤容量、實(shí)現(xiàn)磁盤格式化、移除指定磁盤等,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • C++ STL標(biāo)準(zhǔn)庫std::vector的使用詳解

    C++ STL標(biāo)準(zhǔn)庫std::vector的使用詳解

    vector 是表示可以改變大小的數(shù)組的序列容器,本文主要介紹了C++ STL標(biāo)準(zhǔn)庫std::vector的使用詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 淺談?lì)^文件algorithm中的常用函數(shù)

    淺談?lì)^文件algorithm中的常用函數(shù)

    下面小編就為大家?guī)硪黄獪\談?lì)^文件algorithm中的常用函數(shù)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • C語言函數(shù)語法詳解

    C語言函數(shù)語法詳解

    本文是小結(jié)了一下C語言的函數(shù)語法,詳細(xì)介紹了C語言函數(shù)語法的概述、函數(shù)的定義、函數(shù)的返回值、函數(shù)調(diào)用等7個(gè)方面的內(nèi)容,非常詳細(xì),這里推薦給小伙伴們。
    2015-02-02
  • c++中c_str()的用法示例

    c++中c_str()的用法示例

    這篇文章主要介紹了c++中c_str()的用法示例,幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下
    2020-09-09
  • C# interface與delegate效能比較的深入解析

    C# interface與delegate效能比較的深入解析

    本篇文章是對(duì)C#中interface與delegate的效能比較進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 詳解C++中vector的理解以及模擬實(shí)現(xiàn)

    詳解C++中vector的理解以及模擬實(shí)現(xiàn)

    vector是表示可變大小數(shù)組的序列容器。這篇文章主要為大家詳細(xì)介紹了vector的理解以及模擬實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-03-03
  • C++基于控制臺(tái)實(shí)現(xiàn)的貪吃蛇小游戲

    C++基于控制臺(tái)實(shí)現(xiàn)的貪吃蛇小游戲

    這篇文章主要介紹了C++基于控制臺(tái)實(shí)現(xiàn)的貪吃蛇小游戲,實(shí)例分析了貪吃蛇游戲的原理與C++實(shí)現(xiàn)技巧,是非常經(jīng)典的游戲算法,需要的朋友可以參考下
    2015-04-04
  • 詳解c++ libuv工作隊(duì)列

    詳解c++ libuv工作隊(duì)列

    這篇文章主要介紹了c++ libuv工作隊(duì)列的相關(guān)資料,幫助大家更好的理解和使用libuv,感興趣的朋友可以了解下
    2021-02-02

最新評(píng)論