訪問(wèn)者模式允許在不修改類的情況下為類層次結(jié)構(gòu)添加新操作,通過(guò)定義訪問(wèn)者接口ShapeVisitor,實(shí)現(xiàn)元素接口Shape及其具體類Circle和Rectangle,接著實(shí)現(xiàn)具體訪問(wèn)者如AreaCalculator和InfoPrinter,最後在main函數(shù)中創(chuàng)建對(duì)象並調(diào)用accept方法完成雙分派;該模式遵循開(kāi)閉原則,新增操作只需擴(kuò)展訪問(wèn)者類,無(wú)需改動(dòng)現(xiàn)有元素類,適用於圖形處理、編譯器AST等場(chǎng)景。
在C 中,訪問(wèn)者模式(Visitor Pattern)是一種行為設(shè)計(jì)模式,它允許你在不修改類的情況下為類層次結(jié)構(gòu)添加新的操作。它通過(guò)將操作分離到獨(dú)立的“訪問(wèn)者”對(duì)像中來(lái)實(shí)現(xiàn)“開(kāi)閉原則”。

下面是一個(gè)簡(jiǎn)單的C 訪問(wèn)者模式示例,演示如何為不同的“元素”(如圖形對(duì)象)添加不同的操作(如計(jì)算面積、打印信息),而無(wú)需修改這些元素類本身。
? 場(chǎng)景:圖形類層次結(jié)構(gòu)(圓形、矩形)
我們有多個(gè)圖形類,想支持多種操作(比如:計(jì)算面積、打印信息),但不想每次新增操作都修改每個(gè)類。

? 1. 定義訪問(wèn)者接口(Visitor)
#include <iostream> #include <cmath> // 前向聲明class Circle; class Rectangle; // 訪問(wèn)者接口class ShapeVisitor { public: virtual ~ShapeVisitor() = default; virtual void visit(Circle* circle) = 0; virtual void visit(Rectangle* rectangle) = 0; };
? 2. 定義元素接口(Shape)和具體類
// 元素基類class Shape { public: virtual ~Shape() = default; virtual void accept(ShapeVisitor* visitor) = 0; }; // 具體元素:圓形class Circle : public Shape { public: explicit Circle(double radius) : radius(radius) {} void accept(ShapeVisitor* visitor) override { visitor->visit(this); } double getRadius() const { return radius; } private: double radius; }; // 具體元素:矩形class Rectangle : public Shape { public: Rectangle(double width, double height) : width(width), height(height) {} void accept(ShapeVisitor* visitor) override { visitor->visit(this); } double getWidth() const { return width; } double getHeight() const { return height; } private: double width, height; };
? 3. 實(shí)現(xiàn)具體訪問(wèn)者
? 面積計(jì)算訪問(wèn)者
class AreaCalculator : public ShapeVisitor { public: void visit(Circle* circle) override { double area = M_PI * circle->getRadius() * circle->getRadius(); std::cout << "Circle area: " << area << std::endl; } void visit(Rectangle* rectangle) override { double area = rectangle->getWidth() * rectangle->getHeight(); std::cout << "Rectangle area: " << area << std::endl; } };
? 打印信息訪問(wèn)者
class InfoPrinter : public ShapeVisitor { public: void visit(Circle* circle) override { std::cout << "Circle with radius " << circle->getRadius() << std::endl; } void visit(Rectangle* rectangle) override { std::cout << "Rectangle " << rectangle->getWidth() << "x" << rectangle->getHeight() << std::endl; } };
? 4. 使用示例(main 函數(shù))
int main() { // 創(chuàng)建圖形對(duì)象Circle circle(5.0); Rectangle rectangle(4.0, 6.0); // 創(chuàng)建訪問(wèn)者AreaCalculator areaCalc; InfoPrinter infoPrinter; // 使用訪問(wèn)者計(jì)算面積circle.accept(&areaCalc); // 輸出面積rectangle.accept(&areaCalc); // 使用訪問(wèn)者打印信息circle.accept(&infoPrinter); // 輸出信息rectangle.accept(&infoPrinter); return 0; }
? 輸出結(jié)果
Circle area: 78.5398 Rectangle area: 24 Circle with radius 5 Rectangle 4x6
? 優(yōu)點(diǎn)總結(jié)
- 新增操作(如“序列化”、“渲染”)只需添加新的
ShapeVisitor
子類,無(wú)需修改現(xiàn)有圖形類。 - 符合開(kāi)閉原則(對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉)。
- 將相關(guān)操作集中到一個(gè)訪問(wèn)者類中,邏輯清晰。
?? 注意事項(xiàng)
- 如果類層次結(jié)構(gòu)頻繁變化(新增圖形類),訪問(wèn)者模式會(huì)變得難維護(hù)(每個(gè)訪問(wèn)者都要實(shí)現(xiàn)新visit 方法)。
- 需要提前知道所有具體類(因?yàn)?code>visit(Circle*)等是顯式聲明的)。
- C 中沒(méi)有多態(tài)分派,所以需要手動(dòng)實(shí)現(xiàn)“雙分派”(通過(guò)
accept
調(diào)用visitor->visit(this)
)。
? 核心機(jī)制:雙分派(Double Dispatch)
shape->accept(visitor); // 第一次分派:調(diào)用具體shape 的accept // → visitor->visit(circle); // 第二次分派:調(diào)用對(duì)應(yīng)visit 方法
這使得運(yùn)行時(shí)能根據(jù)兩個(gè)對(duì)象的類型(shape 和visitor)選擇正確操作。
基本上就這些。這個(gè)例子展示瞭如何用C 實(shí)現(xiàn)訪問(wèn)者模式,適用於需要對(duì)複雜對(duì)象結(jié)構(gòu)執(zhí)行多種操作的場(chǎng)景,比如編譯器AST、圖形渲染、序列化等。

以上是C訪客模式示例的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門(mén)文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6
視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版
神級(jí)程式碼編輯軟體(SublimeText3)

PHP開(kāi)發(fā)AI文本摘要的核心是作為協(xié)調(diào)器調(diào)用外部AI服務(wù)API(如OpenAI、HuggingFace),實(shí)現(xiàn)文本預(yù)處理、API請(qǐng)求、響應(yīng)解析與結(jié)果展示;2.局限性在於計(jì)算性能弱、AI生態(tài)薄弱,應(yīng)對(duì)策略為藉力API、服務(wù)解耦和異步處理;3.模型選擇需權(quán)衡摘要質(zhì)量、成本、延遲、並發(fā)、數(shù)據(jù)隱私,推薦使用GPT或BART/T5等抽象式模型;4.性能優(yōu)化包括緩存、異步隊(duì)列、批量處理和就近區(qū)域選擇,錯(cuò)誤處理需覆蓋限流重試、網(wǎng)絡(luò)超時(shí)、密鑰安全、輸入驗(yàn)證及日誌記錄,以確保系統(tǒng)穩(wěn)定高效運(yùn)行。

獲取std::vector的第一個(gè)元素有四種常用方法:1.使用front()方法,需確保vector非空,語(yǔ)義清晰且推薦日常使用;2.使用下標(biāo)[0],同樣需判空,性能與front()相當(dāng)?shù)Z(yǔ)義稍弱;3.使用*begin(),適用於泛型編程和STL算法配合;4.使用at(0),無(wú)需手動(dòng)判空但性能較低,越界時(shí)拋出異常,適合調(diào)試或需要異常處理的場(chǎng)景;最佳實(shí)踐是先調(diào)用empty()檢查是否為空,再使用front()方法獲取第一個(gè)元素,避免未定義行為。

C 標(biāo)準(zhǔn)庫(kù)通過(guò)提供高效工具幫助開(kāi)發(fā)者提升代碼質(zhì)量。1.STL容器應(yīng)根據(jù)場(chǎng)景選擇,如vector適合連續(xù)存儲(chǔ),list適合頻繁插入刪除,unordered_map適合快速查找;2.標(biāo)準(zhǔn)庫(kù)算法如sort、find、transform能提高效率并減少錯(cuò)誤;3.智能指針unique_ptr和shared_ptr有效管理內(nèi)存,避免泄漏;4.其他工具如optional、variant、function增強(qiáng)代碼安全性與表達(dá)力。掌握這些核心功能可顯著優(yōu)化開(kāi)發(fā)效率與代碼質(zhì)量。

函數(shù)是C 中組織代碼的基本單元,用於實(shí)現(xiàn)代碼重用和模塊化;1.函數(shù)通過(guò)聲明和定義創(chuàng)建,如intadd(inta,intb)返回兩數(shù)之和;2.調(diào)用函數(shù)時(shí)傳遞參數(shù),函數(shù)執(zhí)行後返回對(duì)應(yīng)類型的結(jié)果;3.無(wú)返回值函數(shù)使用void作為返回類型,如voidgreet(stringname)用於輸出問(wèn)候信息;4.使用函數(shù)可提高代碼可讀性、避免重複並便於維護(hù),是C 編程的基礎(chǔ)概念。

C ABI是編譯器生成二進(jìn)制代碼時(shí)遵循的底層規(guī)則,決定了函數(shù)調(diào)用、對(duì)象佈局、名稱改編等機(jī)制;1.它確保不同編譯單元正確交互,2.不同編譯器或版本可能採(cǎi)用不同ABI,影響動(dòng)態(tài)庫(kù)鏈接、STL傳遞、虛函數(shù)調(diào)用等,3.跨平臺(tái)開(kāi)發(fā)、長(zhǎng)期系統(tǒng)維護(hù)、第三方庫(kù)使用等場(chǎng)景需特別注意ABI一致性,4.可通過(guò)宏定義、編譯選項(xiàng)控制ABI,使用工具查看符號(hào)表判斷一致性。

std::is_same用於在編譯時(shí)判斷兩個(gè)類型是否完全相同,返回一個(gè)bool值。 1.基本用法中,std::is_same::value在T和U完全相同時(shí)為true,否則為false,包括const、引用、指針等修飾符不同都會(huì)導(dǎo)致false;2.可結(jié)合std::remove_const、std::remove_reference等類型trait去除類型修飾後再比較,實(shí)現(xiàn)更靈活的類型判斷;3.實(shí)際應(yīng)用中常用於模板元編程,如配合ifconstexpr進(jìn)行條件編譯,根據(jù)類型不同執(zhí)行不同邏輯;4.從C

decltype是C 11用於編譯時(shí)推導(dǎo)表達(dá)式類型的關(guān)鍵字,其推導(dǎo)結(jié)果精確且不進(jìn)行類型轉(zhuǎn)換。 1.decltype(expression)只分析類型,不計(jì)算表達(dá)式;2.對(duì)變量名decltype(x)推導(dǎo)為x的聲明類型,而decltype((x))因左值表達(dá)式推導(dǎo)為x&;3.常用於模板中通過(guò)尾置返回類型auto->decltype(t u)推導(dǎo)返回值;4.可結(jié)合auto簡(jiǎn)化複雜類型聲明,如decltype(vec.begin())it=vec.begin();5.在模板中避免硬編碼類
