2015-09-07 51 views
0
class EventListener 
{ 
public: 
    virtual void onEvent (std::string message) = 0; 
    virtual void onEvent (std::string message, int eventCode) = 0; 
}; 

class CustomEventListener : public EventListener 
{ 
public: 
    void onEvent(std::string message) {}; 
    void onEvent(std::string message, int eventCode) {}; // I want this to throw an error 
}; 

我想這樣做是爲了覆蓋一個重載函數,排除用戶重寫另一個,可能會引發編譯時異常。這可能嗎 ?以相互排斥的方式覆蓋虛擬函數

我想在接口中保留兩個虛函數的原因是爲了保持與已經在其應用程序中廣泛使用第一個函數的用戶的向後兼容性,我不想強​​迫他們使用第二個更新的一。

使這兩個函數非純並不是一個真正的選擇,因爲我想強制用戶重寫其中的一個。

+0

我的C++很生鏽:如果向兩者添加'= 0',我不認爲你可以讓任何一個未被實現,你能嗎?你怎麼知道哪一個被覆蓋,哪些在運行時可以安全地調用? – Rup

+3

你怎麼知道用戶提供了哪一個?我敢肯定,你需要提供默認實現並調用兩者,所以如果用戶覆蓋既沒有不好的事情發生。此外,你只會因爲使這個純虛函數而產生仇恨,如果有人不想重寫'onEvent',那麼他們就不會得到這個事件,爲什麼強迫它們呢? – nwp

+3

添加另一個純虛函數並不完全向後兼容。用戶需要實現它(甚至是微不足道的)並重新編譯它們的類。 – StoryTeller

回答

2

我想要讓這個壓倒一切的重載函數一個從覆蓋的其他排除用戶,可能扔編譯時異常。這可能嗎 ?

不可以根據其他覆蓋有條件地防止覆蓋函數。至少不是標準的C++。

我爲什麼要保留兩個虛函數接口的原因是爲了與用戶保持向後兼容性誰已經在他們的應用程序廣泛使用的第一個功能,我不想強​​迫他們使用第二,更新的一個。

如果向接口添加一個新的純虛函數,那麼所有尚未實現新函數的繼承類將變得抽象。這將打破向後兼容性。

防止用戶實施其中之一不會有幫助。相反,它只會阻止它們創建繼承接口的具體類。

+0

是的,我認爲這是不可能的,但我並不是100%確定。謝謝你的澄清。 – Catalin

2

爲什麼不強制覆蓋只有一個另外的實現方式:

class CustomEventListener : public EventListener { 
public: 
    virtual void onEvent(std::string message) {}; 

private: // <<<<<<<< 
    // I want this to throw an error 
    virtual void onEvent(std::string message, int eventCode) { 
     throw std::runtime_error("Deprecated"); 
    } 
}; 
+0

這個想法是,用戶自己將實現接口,以便他們選擇事件觸發時發生的事情。對不起,我在編寫'CustomEventListener'時犯了一個錯誤。 – Catalin

+0

@Catalin函數覆蓋/實現實際上需要是「虛擬」的。您可以嘗試使用[模板函數模式]爲您的客戶端類提供不同的界面(https://www.google.de/url?sa=t&source=web&rct=j&url=https://sourcemaking.com/design_patterns/template_method/ CPP/1 VED = 0CCAQFjAAahUKEwidssDDguXHAhWM1ywKHQutB60與USG = AFQjCNFPnuiy0gyX5wGz85DenVJhDGPhEw&SIG2 = cKj1lVra4i_NIPgEB5TyWQ) –

+0

@Catalin因爲這些功能會改寫虛函數,他們含蓄虛擬您是否已經標記他們,所以明確與否。 – user2079303

0

正如user2079303回答,你不能像你所建議的那樣做。

但是,你可能會做一些步驟,可以做你想達到的訣竅。

class EventListener 
{ 
public: 
    virtual void onEvent (std::string message) 
    { 
     throw std::runtime_error("Deprecated"); 
    } 
    virtual void onEvent (std::string message, int eventCode) 
    { 
     onEvent(message); 
    } 
}; 

舊類仍可以僅覆蓋第一個方法。

class CustomEventListener : public EventListener 
{ 
public: 
    void onEvent(std::string message) {}; 
}; 

新類強制(因此只除外)覆蓋其中的一個,這樣他們就可以是這樣的:

class CustomEventListener : public EventListener 
{ 
public: 
    void onEvent(std::string message, int eventCode) {}; 
}; 

不幸的是用戶也可以覆蓋他們兩個,但有你無能爲力。

要正確處理這種情況,應該在代碼中調用第二種方法。