我见过几个展示访客模式的例子。 在所有这些中,每个派生的访问元素都实现了通常称为Accept()方法的内容。
在颜色层次结构中,此方法可能如下所示:
void Red::accept(Visitor *v)
{
v->visit(*this);
}
void Blue::accept(Visitor *v)
{
v->visit(*this);
}
当访问者及其继承者拥有方法时:
visit(Red red);
visit(Blue blue)
我的问题是为什么不在基类中以相同的方式实现它(在这个例子中:Color
)并且多态将完成这项工作,即,当对象是什么时,将调用正确的访问Red
这个动态类型是Red
,因此取消引用它会产生Red
,这反过来会导致访问(红色)被调用?
我错过了什么?
答案 0 :(得分:8)
继承多态(动态分派)不适用于函数参数。换句话说,在传递的参数的静态类型上选择重载函数。如果在基类Color
中实施,则v->visit(*this)
始终会调用visit(Color c)
。
答案 1 :(得分:1)
如果你唯一的accept
是......
void Color::accept(Visitor* v)
{
v->visit(*this);
}
只需用基类调用 visit
。为了使用正确的派生类调用visit
,您需要每个Color
来实现它,以便他们可以传递正确键入的this
,从而调用正确的visit
重载。
答案 2 :(得分:1)
我的理解是,在基类方法中,this
指针的类型是base,而不是任何派生类,因此它只能访问基类方法,并作为类型Color* this
传递。当传递给visit方法时,它会尝试运行visit(Color* color)
,因为多态行为只适用于类本身的方法(而不是其他类)。