这个问题更像是理论上的。
前言。
访客模式:
class Visitor
{
public:
virtual void VisitElementA(const ElementA& obj) = 0;
virtual void VisitElementB(const ElementB& obj) = 0;
};
class Element
{
public:
virtual void Accept(Visitor& visitor) = 0;
};
class ElementA : public Element
{
public:
void Accept(Visitor& visitor) override { visitor.VisitElementA(*this); }
};
class ElementB : public Element
{
public:
void Accept(Visitor& visitor) override { visitor.VisitElementB(*this); }
};
这个 VisitElementA(const ElementA& obj) 看起来有点难看,所以使用重载我们可以像这样重写它:
class Visitor
{
public:
virtual void Visit(const ElementA& obj) = 0;
virtual void Visit(const ElementB& obj) = 0;
};
现在我们在 ElementA 和 ElementB 中有两个相同的 Accept 方法实现:
void Accept(Visitor& visitor) override { visitor.Visit(*this); }
并且必须将此类代码添加到 ElementC、ElementD 等(如果有)
问题是:如何避免这种重复?
将 Accept 实现放在 Element 类(或其他中间类)中的天真解决方案将不起作用,因为该指针将指向类 Element 的对象,而不是 ElementA 或 ElementB,因此在最好的情况下,我们将得到编译错误,甚至错误的行为(如果 Element 会有一些重载的 Visit 方法)。
据我了解,问题在于尝试混合编译时和运行时功能。但可能存在一些基于模板的解决方案或新的 C++11 功能,还是其他?
请注意:如果您不提供“宏魔法”的解决方案,我将不胜感激:)。