2017-05-30 171 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