日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++示例講解觀察者設計模式_C 語言

作者:編程遠泊 ? 更新時間: 2023-02-02 編程語言

引言

用來解決兩個不相關對象之間的一對一或者一對多的通信模型。

什么是觀察者設計模式

觀察者模式是一種對象行為模式。它定義對象間的一種一對多的依賴關系, 當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。在觀察者模式中,主體是通知的發布者,它發出通知時并不需要知道誰是它的觀察者,可以有任意數目的觀察者訂閱并接受通知。觀察者模式不僅被廣泛應用于軟件界面元素之間的交互,在業務對象之間的交互、權限管理等方面也有廣泛的應用。

解決的問題

定義了對象間的一種一對多的組合關系,以便一個對象的狀態發生時,所有依賴于它的對象都得到通知并自動刷新。

觀察者和被觀察者之間存在“觀察”的邏輯關系,當被觀察者發生變化時,觀察者就會觀察到這樣的變化,并作出相應的響應。

編程思路

設定兩者類,一個為觀察者類,一個為被觀察者類

觀察者類中,定義一個對某個事件感興趣的處理函數,一般也叫做槽函數

被觀察者類中,定義一個數據結構,用來保存觀察者對某一個事件id(信號)感興趣,使用數據結構建立信號與對象之間的映射關系

被觀察者類中,定義兩個方法函數:

一個方法為:添加觀察者與其感興趣的事件id(信號)加入到容器中

另一個方法為:信號函數:通知事件函數執行邏輯:首先遍歷容器中,有沒有感興趣的事件ID,如果有,則代表一系列的觀察者,對這個事件感興趣,那么再次遍歷觀察者列表,讓每一個觀察者執行相應的槽函數

#include <iostream>
#include <map>
#include <list>
using namespace std;
class RecvBase
{
public:
    RecvBase()
    {
        cout << "RecvBase structure" <<  endl;
    }
    virtual void slotFunctions(int msgid)=0;
    virtual ~RecvBase()
    {
        cout << "RecvBase destruct" << endl;
    }
};
class Recv:public RecvBase
{
public:
    Recv()
    {
        cout << "Recv structure" << "---" << this << "---" << endl;
    }
    void slotFunctions(int msgid)override
    {
        switch(msgid)
        {
        case 1:
            cout << this << "接收到1信號,執行1信號對應的槽函數" << endl;
            break;
        case 2:
            cout << this << "接收到2信號,執行2信號對應的槽函數" << endl;
            break;
        case 3:
            cout << this << "接收到3信號,執行3信號對應的槽函數" << endl;
            break;
        case 4:
            cout << this << "接收到4信號,執行4信號對應的槽函數" << endl;
            break;
        }
    }
    ~Recv()override
    {
        cout << "Recv destruct" << endl;
    }
};
class Sender
{
public:
    Sender()
    {
        cout << "sender structure" << endl;
    }
    map<int,list<RecvBase* >> RecvMap;
    void observerToRecvMap(int msgid,RecvBase* recv)
    {
        this->RecvMap[msgid].push_back(recv);
    }
    void senderSignals(int msgid)
    {
        auto it = RecvMap.find(msgid);
        if(it!=RecvMap.end())
        {
            for(RecvBase* p:it->second)
            {
                p->slotFunctions(msgid);
            }
        }else{
            cout << "接收到未知信號,沒有對應的可執行槽函數" << endl;
        }
    }
    ~Sender()
    {
        cout << "sender destruct" << endl;
    }
};
int main()
{
    Sender sender;
    RecvBase* r1=new Recv();
    RecvBase* r2=new Recv();
    RecvBase* r3=new Recv();
    RecvBase* r4=new Recv();
    sender.observerToRecvMap(1,r1);
    sender.observerToRecvMap(1,r2);
    sender.observerToRecvMap(2,r2);
    sender.observerToRecvMap(3,r3);
    sender.observerToRecvMap(4,r4);
    while(true)
    {
        int msgid;
        cin >> msgid;
        if(-1==msgid)break;
        sender.senderSignals(msgid);
    }
    delete r1;
    delete r2;
    delete r3;
    delete r4;
    return 0;
}

知識小百科

this指針:

  • 是本對象的起始地址,用const修飾的常地址(原型:stu *const this)(本文代碼中this的作用)
  • 是隱藏在成員函數(非靜態函數)的最左側的常變量形參

作用:

  • 區別成員屬性和成員函數的形參
  • 解引用,返回本對象的地址

原文鏈接:https://blog.csdn.net/distant_Rove666/article/details/128430279

欄目分類
最近更新