访问者模式如何避免向下转换 [英] How Visitor Pattern avoid downcasting

查看:129
本文介绍了访问者模式如何避免向下转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以显示示例代码之前和之后,以避免向下投射访问者模式代码?

can anyone show example code before and after to avoid down casting for visitor pattern code ?

谢谢。

推荐答案

一个简单的简单例子。

class Base {};
class Derived1 : public Base {};
class Derived2 : public Base {};

// Some arbitrary function that handles Base.
void
Handle(Base& obj) {
    if (...type is Derived1...) {
        Derived1& d1 = static_cast<Derived1&>(base);
        std::printf("Handling Derived1\n");
    }
    else if (...type is Derived2...) {
        Derived2& d2 = static_cast<Derived2&>(base);
        std::printf("Handling Derived2\n");
    }
}

这意味着 code>必须有一些类型标签字段,或者您将使用 dynamic_cast 检查每种类型。

This means Base must have some type tag field, or you will be using dynamic_cast to check for each type.

// 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);
}




  1. 是在 obj (首次发送)类型上发送的虚拟函数

  2. 重载访问(),因为 Accept()已经知道对象的类型。
  3. Visit()反过来是根据访问者类型(第二个调度)分派的虚拟函数。

  1. Accept() is a virtual function that dispatches on the type of obj (first dispatch)
  2. It then calls appropriate overload of Visit(), because inside Accept() you already know the type of your object.
  3. Visit(), in turn, is a virtual function that dispatches on the type of visitor (second dispatch).

因为你有双重分派(一个对象,另一个访问者),你不做任何投射。缺点是,任何时候你添加一个类到你的层次结构,你必须去更新你的访问者类添加一个适当的函数来处理新的子类。

Because you have double dispatch (one on object, another on visitor), you don't do any casting. The downside is that any time you add a class to your hierarchy, you have to go and update your visitor class to add an appropriate function to handle the new subclass.

这篇关于访问者模式如何避免向下转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆