表示一個作用於某對象結構中各元素的操作。它使你可以在不改變各元素類別的前提下,定義作用於這些元素的新操作。

Element::Accept(Visitor&),再由具體元素呼叫 Visitor::VisitConcreteElement(this)。兩次動態綁定確定具體操作。#ifndef VISITOR_H
#define VISITOR_H
class Visitor;
// 元素抽象基類
class Element {
public:
virtual ~Element() {}
virtual void Accept(Visitor& rVisitor) = 0;
protected:
Element() {}
};
// 具體元素 A
class ConcreteElementA : public Element {
public:
virtual ~ConcreteElementA() {}
virtual void Accept(Visitor& rVisitor);
};
// 具體元素 B
class ConcreteElementB : public Element {
public:
virtual ~ConcreteElementB() {}
virtual void Accept(Visitor& rVisitor);
};
// 訪問者抽象基類:針對每種元素宣告訪問介面
class Visitor {
public:
virtual ~Visitor() {}
virtual void VisitConcreteElementA(ConcreteElementA* p) = 0;
virtual void VisitConcreteElementB(ConcreteElementB* p) = 0;
protected:
Visitor() {}
};
// 具體訪問者 A
class ConcreteVisitorA : public Visitor {
public:
virtual ~ConcreteVisitorA() {}
virtual void VisitConcreteElementA(ConcreteElementA* p);
virtual void VisitConcreteElementB(ConcreteElementB* p);
};
// 具體訪問者 B
class ConcreteVisitorB : public Visitor {
public:
virtual ~ConcreteVisitorB() {}
virtual void VisitConcreteElementA(ConcreteElementA* p);
virtual void VisitConcreteElementB(ConcreteElementB* p);
};
#endif
#include "Visitor.h"
#include <iostream>
void ConcreteElementA::Accept(Visitor& rVisitor) {
rVisitor.VisitConcreteElementA(this);
}
void ConcreteElementB::Accept(Visitor& rVisitor) {
rVisitor.VisitConcreteElementB(this);
}
void ConcreteVisitorA::VisitConcreteElementA(ConcreteElementA* p) {
std::cout << "VisitConcreteElementA By ConcreteVisitorA\n";
}
void ConcreteVisitorA::VisitConcreteElementB(ConcreteElementB* p) {
std::cout << "VisitConcreteElementB By ConcreteVisitorA\n";
}
void ConcreteVisitorB::VisitConcreteElementA(ConcreteElementA* p) {
std::cout << "VisitConcreteElementA By ConcreteVisitorB\n";
}
void ConcreteVisitorB::VisitConcreteElementB(ConcreteElementB* p) {
std::cout << "VisitConcreteElementB By ConcreteVisitorB\n";
}
#include "Visitor.h"
int main() {
Visitor* pVisitorA = new ConcreteVisitorA();
Element* pElement = new ConcreteElementA();
pElement->Accept(*pVisitorA); // 雙重分派觸發
delete pElement;
delete pVisitorA;
return 0;
}
std::variant + std::visit)替代。