2017-05-30 72 views
1

在C++中对访问者模式进行实验后,就实现派生接口而言,我遇到了一个愚蠢的问题。我怀疑我不知道如何正确地提出问题,因为我还没有在其他地方找到解决方案。C++结构实现派生接口

我有以下基本结构:

struct Visitor { 
    virtual void visit(const Resources) = 0; 
    virtual void visit(const Population) = 0; 
}; 

我要申报情侣游客的具体实现的一些额外的功能一起。 这是我多么希望我的声明看起来像

struct EndVisitor : public Visitor{ 
    virtual bool hasEnded(); 
}; 

struct SetupVisitor : public Visitor{ 
}; 

struct ScoreVisitor : public Visitor{ 
    virtual unsigned int getScore(); 
}; 

定义时,例如说ScoreVisitor的IDE和编译器可识别额外的函数声明中ScoreVisitor:

unsigned int ScoreVisitor::getScore() { 
    return total; 
} 

然而,实施访客功能不被编译器或IDE识别(Funtion 'visit' not declared in class 'ScoreVisitor'):

void ScoreVisitor::visit(const Resources resources) { 
    total += resources.score; 
} 

void ScoreVisitor::visit(const Population population) { 
    total += population.score; 
} 

如果我宣布ScoreVisitor重复访问者功能,代码将会编译,但是这使我在Visitor的所有专门声明中留下了大量的复制粘贴代码,我希望避免这些代码。 这不是我多么希望我的声明看起来像

struct ScoreVisitor : public Visitor{ 
    virtual void visit(const Resources); 
    virtual void visit(const Population); 
    virtual unsigned int getScore(); 
}; 

我如何申报观众的专门版本,而不必复制粘贴所有游客已经声明了功能?

+3

欢迎来到C++!在定义它们之前,您需要正确声明任何类的所有成员。即使你从基类重写的虚拟方法。 – Nim

+0

谢谢Nim!我理解你的答复如下:我无法避免在Visitor的专门声明中声明接口函数? – Yakitawa

+1

是的,除非你有一个层次结构,其中一些功能是在不同的抽象层次实现的。 – Nim

回答

2

没有办法避免必须从派生类中的基类声明重写的方法。这是语言的方式。通常,人们将功能分组为某种形式的继承层次结构,以公开常见的功能。

注意几个语法相关事宜,virtual是可选的派生类(具有类似特征的功能是通过默认虚拟),因为C++ 11,一些人已经采取措施来使用override(我属于这一类),因为它会捕获 - 在编译时 - 在派生类中预期方法是虚拟的任何情况,但在基类中它不会被声明为这样。

我确定上面是一个例子,但重要的是你不要忘记基类中的虚析构函数!

1

它的不理想,但你可以用它从观众继承的子类做到这一点,并有其他类从中导出:

struct Visitor { 
    virtual void visit(const int) = 0; 
}; 

struct VisitorImplementor : public Visitor 
{ 
    virtual void visit(const int) override { /* implement */} 
}; 


struct EndVisitor : public VisitorImplementor { 
    virtual bool hasEnded() { return true; } 
}; 

现在你可以创建EndVisitor的实例,并调用访问它

EndVisitor v; 

v.visit(10); 
+0

谢谢Servé!我看到如何实现这些功能可以完成关于使它们在派生类中可见的技巧。但是,这个问题的方向与问题相反:我希望尽可能的懒,因此我想排除派生类的实现,除了最后一个。 – Yakitawa