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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

设计模式(17) 访问者模式(VISITOR) C++实现

發(fā)布時間:2025/3/15 c/c++ 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式(17) 访问者模式(VISITOR) C++实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

意圖:

??? 表示一個作用于某對象結(jié)構(gòu)的各元素的操作。它使你可以再不改變各元素的類的前提下定義作用于這些元素的新操作。

?

動機:

??? 之前在學校的最后一個小項目就是做一個編譯器,當時使用的就是訪問者模式。

??? 在靜態(tài)分析階段,將源程序表示為一個抽象語法樹,編譯器需要在抽象語法樹的基礎上實施某些操作以進行靜態(tài)語義分析。可能需要定義許多操作以進行類型檢查、代碼優(yōu)化、流程分析、檢查變量是否在使用前被賦值,等等。

??? 這個需求的特點是:要求對不同的節(jié)點進行不同的處理。

??? 常規(guī)設計方法:不同的節(jié)點封裝不同的操作。

??? 缺點是,節(jié)點類型過多,將操作分散在各個節(jié)點類中會導致整個系統(tǒng)難以理解、維護和修改。增加新的操作要修改和重新編譯所有的類。

??? 改進:節(jié)點類獨立于作用于其上的操作。

??????? 1 將相關操作封裝在一個獨立的對象(Visitor)中,并在遍歷抽象語法樹時將此對象傳遞給當前訪問的元素。

??????? 2 當一個節(jié)點接受一個訪問者時,該元素向訪問者發(fā)送一個包含自身類信息的請求。該請求同時也將該元素本身作為一個參數(shù)。

??????? 3 訪問者將對該元素執(zhí)行該操作。

?

適用性:

??? 在下列情況下使用Visitor模式:

??? 一個對象結(jié)構(gòu)包含很多類對象

??? 需要對其中的對象進行很多不同的并且不相關的操作

??? 對象很少改變,經(jīng)常需要對其上的操作進行修改或新增

??? 需要注意的一點是,如果對象結(jié)果和接口經(jīng)常改變,那么會導致需要重定義所有訪問者的接口,會導致很大的代價。所以這種情況還是在對象類中定義操作比較好。

?

結(jié)構(gòu):

?

協(xié)作:

?

示例代碼:

背景:假設你的電腦出現(xiàn)問題了 ,拿到售后那邊檢測,售后告訴你必須拆機檢測,檢測過程通過兩個技術人員依次負責不同功能的檢測。

分析:本例中,兩個負責不同功能檢測的技術人員就是Visitor,而電腦的各個部件就是elements。

特點:電腦的部件是固定的,不會有太大的改變,但是如果一種檢測方式?jīng)]有找出問題的話,那么就需要增加檢測項。符合訪問者模式的特點。

//visit.h#ifndef VISITOR_H #define VISITOR_H#include <iostream> #include <string> #include <vector>class Element; class CPU; class VideoCard; class MainBoard;/*------------------*/ class Visitor { public:Visitor(std::string name) {visitorName = name;}virtual void visitCPU( CPU* cpu ) {};virtual void visitVideoCard( VideoCard* videoCard ) {};virtual void visitMainBoard( MainBoard* mainBoard ) {};std::string getName() {return this->visitorName;}; private:std::string visitorName; };class Element { public:Element( std::string name ) {eleName = name;}virtual void accept( Visitor* visitor ) {};virtual std::string getName() {return this->eleName;} private:std::string eleName; };/*----------- Elements -------------*/class CPU : public Element { public:CPU(std::string name) : Element(name) {}void accept(Visitor* visitor) {visitor->visitCPU(this);} };class VideoCard : public Element { public:VideoCard(std::string name) : Element(name) {}void accept(Visitor* visitor) {visitor->visitVideoCard(this);} };class MainBoard : public Element { public:MainBoard(std::string name) : Element(name) {}void accept(Visitor* visitor) {visitor->visitMainBoard(this);} };/*----------- ConcreteVisitor -------------*/class CircuitDetector : public Visitor { public:CircuitDetector(std::string name) : Visitor(name) {}// checking cpuvoid visitCPU( CPU* cpu ) {std::cout << Visitor::getName() << " is checking CPU's circuits.(" << cpu->getName()<<")" << std::endl;}// checking videoCardvoid visitVideoCard( VideoCard* videoCard ) {std::cout << Visitor::getName() << " is checking VideoCard's circuits.(" << videoCard->getName()<<")" << std::endl;}// checking mainboardvoid visitMainBoard( MainBoard* mainboard ) {std::cout << Visitor::getName() << " is checking MainBoard's circuits.(" << mainboard->getName() <<")" << std::endl;}};class FunctionDetector : public Visitor { public:FunctionDetector(std::string name) : Visitor(name) {}virtual void visitCPU( CPU* cpu ) {std::cout << Visitor::getName() << " is check CPU's function.(" << cpu->getName() << ")"<< std::endl;}// checking videoCardvoid visitVideoCard( VideoCard* videoCard ) {std::cout << Visitor::getName() << " is checking VideoCard's function.(" << videoCard->getName()<< ")" << std::endl;}// checking mainboardvoid visitMainBoard( MainBoard* mainboard ) {std::cout << Visitor::getName() << " is checking MainBoard's function.(" << mainboard->getName() << ")"<< std::endl;} };/*------------------------*/class Computer { public:Computer(CPU* cpu,VideoCard* videocard,MainBoard* mainboard) {elementList.push_back(cpu);elementList.push_back(videocard);elementList.push_back(mainboard);};void Accept(Visitor* visitor) {for( std::vector<Element*>::iterator i = elementList.begin(); i != elementList.end(); i++ ){(*i)->accept(visitor);}}; private:std::vector<Element*> elementList; };#endif

?

?

// main.cpp#include "visitor.h"int main() {CPU* cpu = new CPU("Intel CPU");VideoCard* videocard = new VideoCard("XXX video card");MainBoard* mainboard = new MainBoard("HUAWEI mainboard");Computer* myComputer = new Computer(cpu, videocard, mainboard);CircuitDetector* Dan = new CircuitDetector("CircuitDetector Dan");FunctionDetector* Tom = new FunctionDetector("FunctionDetector Tom");std::cout << "\nStep 1: Dan is checking computer's circuits." << std::endl;myComputer->Accept(Dan);std::cout << "\nStep 2: Tom is checking computer's functions." << std::endl;myComputer->Accept(Tom);system("Pause");return 0; }

?

?

運行截圖:

?

?

?

參考資料:

《設計模式:可復用面向?qū)ο筌浖幕A》

轉(zhuǎn)載于:https://www.cnblogs.com/suzhou/p/designpattern17visitor.html

總結(jié)

以上是生活随笔為你收集整理的设计模式(17) 访问者模式(VISITOR) C++实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。