C++ 访客模式如何避免沮丧
任何人都可以在前后显示示例代码以避免访问者模式代码的降级吗C++ 访客模式如何避免沮丧,c++,visitor,C++,Visitor,任何人都可以在前后显示示例代码以避免访问者模式代码的降级吗 谢谢 该示例使用双重分派,没有向下投射。一个简单的、最低限度的示例 之前 这就是框架。现在实现实际的访问者以多态方式处理对象 // Implementing custom visitor class Printer : public Visitor { virtual void Visit(Derived1& d1) { std::printf("Handling Derived1\n"); }
谢谢 该示例使用双重分派,没有向下投射。一个简单的、最低限度的示例 之前 这就是框架。现在实现实际的访问者以多态方式处理对象
// Implementing custom visitor
class Printer : public Visitor {
virtual void Visit(Derived1& d1) { std::printf("Handling Derived1\n"); }
virtual void Visit(Derived2& d2) { std::printf("Handling Derived2\n"); }
};
// Some arbitrary function that handles Base.
void
Handle(Base& obj)
{
Printer p;
obj.Accept(p);
}
Accept()
是一个虚拟函数,它以obj
的类型进行调度(首次调度)Visit()
,因为在Accept()
中,您已经知道对象的类型Visit()
因为您有双重分派(一个在对象上,另一个在访问者上),所以您不进行任何铸造。缺点是,任何时候向层次结构添加类时,都必须更新访问者类,以添加适当的函数来处理新的子类。我理解您的解释,但我想知道在示例中应用访问者模式之前,类层次结构的用途是什么。我想知道handle方法是在基类还是派生类中。派生类实现的典型示例是什么?@peterwkc,我添加了类层次结构。它完全一样,除了没有访客位
Handle()
只是一个任意函数,它可以运行到任何地方(无论在哪里)。作为层次结构一部分的派生类必须实现Accept()
,并自己调用访问者。最后一点不是缺点,而是优点。在编译时被迫更新访问者类通常比跟踪几十条if-else语句的向下转换要好。
// Class definitions
class Visitor;
class Base {
public:
// This is for dispatching on Base's concrete type.
virtual void Accept(Visitor& v) = 0;
};
class Derived1 : public Base {
public:
// Any derived class that wants to participate in double dispatch
// with visitor needs to override this function.
virtual void Accept(Visitor& v);
};
class Derived2 : public Base {
public:
virtual void Accept(Visitor& v);
};
class Visitor {
public:
// These are for dispatching on visitor's type.
virtual void Visit(Derived1& d1) = 0;
virtual void Visit(Derived2& d2) = 0;
};
// Implementation.
void
Derived1::Accept(Visitor& v) {
v.Visit(*this); // Calls Derived1 overload on visitor
}
void
Derived2::Accept(Visitor& v) {
v.Visit(*this); // Calls Derived2 overload on visitor
}
// Implementing custom visitor
class Printer : public Visitor {
virtual void Visit(Derived1& d1) { std::printf("Handling Derived1\n"); }
virtual void Visit(Derived2& d2) { std::printf("Handling Derived2\n"); }
};
// Some arbitrary function that handles Base.
void
Handle(Base& obj)
{
Printer p;
obj.Accept(p);
}