2016-09-29 20 views
0

考慮下面的C++示例main.cpp文件:故意隱藏重載函數警告避免

class FooIf 
{ 
public: 
    virtual int handle(char *req, char *res) = 0; 
}; 

class BarIf 
{ 
public: 

    virtual void handle(char *msg) = 0; 
}; 

class Bar : private BarIf 
{ 
private: 
    void handle(char * msg){} 
}; 

class Zoo : public FooIf, public Bar 
{ 
public: 
    using FooIf::handle; 
public: 
    int handle(char *req, char *res){ return (0); } 
}; 

int main(){ 

    Zoo zoo; 
    return (0); 
} 

我得到這樣的警告:

$ clang++ -ggdb -c main.cpp -Wall 
main.cpp:23:6: warning: 'Zoo::handle' hides overloaded virtual function [-Woverloaded-virtual] 
     int handle(char *req, char *res){ return (0); } 
      ^
main.cpp:17:7: note: hidden overloaded virtual function 'Bar::handle' declared here: different number of parameters (1 vs 2) 
     void handle(char * msg){} 
      ^

現在..我確實隱藏Bar::handle和我這樣做故意的

有沒有辦法避免壓制警告,同時得到這個?

沒有必要說g++根本就不抱怨。

+1

你不應該故意這樣做。你打敗了多態的意圖。如果你不想要多態,請使用封裝。 –

+0

我看不到你的觀點,你能舉個例子嗎?我發現這是唯一的答案在這裏給出(http://stackoverflow.com/questions/18515183/c-overloaded-virtual-function-warning-by-clang),絕對看起來更像是一個藉口,而不是一個真正的動機。 我很樂意避免刪除警告,但不想因爲叮噹想阻止我輸入錯誤而使用代碼。 –

+1

句柄的定義在錯誤的地方。多態基類迫使所有派生類實現基類中的所有方法。所以從BarIf中刪除handle(),因爲你不需要它 - 或者從別的東西中派生Zoo –

回答

5

你應該考慮一個不同的設計。如果你真的需要這個,這看起來像是一個代碼異味/設計問題。

如果(無論出於何種原因)您確實希望這樣做,您可以在特定位置關閉警告。看到這裏的信息http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas

在你情況下,這看起來像這樣

class Zoo : public FooIf, public Bar 
{ 
public: 
    using FooIf::handle; 
public: 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Woverloaded-virtual" 
    int handle(char *req, char *res){ return (0); } 
#pragma clang diagnostic pop 
}; 
+0

真的很感激,但我錯過了關於錯誤設計的觀點..如果我給一個'handle'方法一個不同的名字,它將會非常好。 這裏的設計是一個繼承自虛擬純接口和另一個類的類,它意外地有一個碰撞名稱的方法。這種設計有什麼問題? –

+2

@RiccardoManfrin爲什麼需要將它隱藏在第一位?爲什麼不將函數重命名爲適當的? 「處理」是一個非常通用的名稱。我無法真正告訴你這個設計中的問題沒有細節。正如我所說這是一種代碼味道。有些東西聞起來不對,通常表明您的設計存在問題。這可能會導致意外的行爲,如果有人看到它來自BarIf並調用句柄並期望調用「BarIf :: handle」。編譯器不會捕獲這個,所以你遇到潛在的運行時錯誤。 – Hayt

+0

你對這個(重命名)是正確的,我即將解決這個問題。然而,如果重命名是解決方案,那麼設計並不是必然的錯誤。 有關設計的詳細信息: Zoo等同於Bar,並且必須公開完全相同的API,以及一些額外的專門化方法:它是Bar的特殊化,它擴展了它的屬性,但必須公開相同的API(我會不想重寫)。 與此同時,Zoo還必須響應另一個由完全不同的組件定義的(完全不同的)由ZooIf定義的API。 –

1

警告識別可能的問題。

可能是一個關鍵詞在這裏。如果您忽略警告,您的代碼可以完全正常運行。但是,數百萬開發者的經驗讓數以萬億計的代碼行使編譯器說「這是一個糟糕的主意」。

修復它包含抑制警告或簡單地重命名該方法。

這是一個潛在的警告,因爲該類中的handle的含義在很大程度上取決於您如何調用它。另外,有時候人們不小心失敗通過給它一個稍微不同的簽名來重載一個函數。

在這兩者之間,認爲值得將其標記爲警告。

解決問題的最佳途徑將取決於您的問題中未顯示的細節。

+0

是的,我想要了解的是警告的動機是...而且在我看來這很容易:不要以相同的方式調用兩個函數,即使它們不具有不同的指紋彼此相關,因爲這可能會混淆人們.. –