需要在类体系中加入一个新的虚函数,但不允许改动。
Visitor模式,核心是:将操作作为数据对象传递给类体系预留的Accept函数。
class Personnel{
public:virtual void Pay () = 0;virtual void Promote() = 0;virtual void Accept(Visitor &) = 0;
};
class Officer : public Personnel { /* 改写虚拟函数 */ };
class Captain : public Officer { /* 改写虚拟函数 */ };
class First : public Officer { /* 改写虚拟函数 */ };
Visitor模式:行为型设计模式。允许为对象结构的元素添加进一步的操作,而不必修改这些元素的类。以下为示例:
class Element {
public:virtual ~Element() {}virtual void accept(class Visitor &v) = 0;
};
class ConcreteElementA : public Element {
public:void accept(Visitor &v) override{v.visit(*this);}void operationA() {std::cout << "Element A operation." << std::endl;}
};
class ConcreteElementB : public Element {
public:void accept(Visitor &v) override{v.visit(*this);}void operationB() {std::cout << "Element B operation." << std::endl;}
};
class Visitor {
public:virtual ~Visitor() {}virtual void visit(ConcreteElementA &element) = 0;virtual void visit(ConcreteElementB &element) = 0;
};
class ConcreteVisitor : public Visitor {
public:void visit(ConcreteElementA &element) override {element.operationA();std::cout << "Visited by ConcreteVisitor." << std::endl;}void visit(ConcreteElementB &element) override {element.operationB();std::cout << "Visited by ConcreteVisitor." << std::endl;}
};
class NewOperationVisitor : public Visitor { //这个就是新增的操作范例
public:void visit(ConcreteElementA &element) override {std::cout << "New operation visited Element A." << std::endl;}void visit(ConcreteElementB &element) override {std::cout << "New operation visited Element B." << std::endl;}
};
int main() {ConcreteElementA elementA;ConcreteElementB elementB;ConcreteVisitor visitor; //原操作elementA.accept(visitor);elementB.accept(visitor);NewOperationVisitor newOperationVisitor;//这个就是新增的操作范例elementA.accept(newOperationVisitor);elementB.accept(newOperationVisitor);return 0;
}
以下为改写前面的代码
class Visitor {
public:virtual void Visit( Personnel& ) = 0;virtual void Visit( Officer& ) = 0;virtual void Visit( Captain& ) = 0;virtual void Visit( First& ) = 0;
};
void Personnel::Accept( Visitor & v ) { v.Visit( *this ); }
void Officer::Accept ( Visitor & v ) { v.Visit( *this ); }
void Captain::Accept ( Visitor & v ) { v.Visit( *this ); }
void First::Accept ( Visitor & v ) { v.Visit( *this ); }
class DoSomething : public Visitor {
public:virtual void Visit( Personnel& );virtual void Visit( Officer& );virtual void Visit( Captain& );virtual void Visit( First& );
};
void DoSomething::Visit( Captain& c ){if( femaleGuestStarIsPresent )c.TurnOnCharm();elsec.StartFight();
}
void DoSomething::Visit( First& f ){f.RaiseEyebrowAtCaptainsBehavior();
}
void f( Personnel& p ){p.Accept( DoSomething() );
}
int main(){Captain k;First s;f( k );f( s );
}