2017-01-01 51 views
2

如果之前有人問過這個問題,我很抱歉,我努力尋找類似的東西,但我甚至不知道要搜索什麼。什麼是定義自引用界面的正確方法?

假設我有如下界面(這只是一個例子,我的具體情況什麼都沒有與運營商或除做):

class AddAndSub 
{ 
public: 
    virtual AddAndSub operator +(AddAndSub const &) = 0; 
    virtual AddAndSub operator -(AddAndSub const &) = 0; 
} 

由於a + b可以表示爲a - (-b)a - b作爲a + (-b)(爲簡單讓我們假設所有派生類型的否定都是明確的)我的第一本能是在實現中模擬這個屬性,所以只需要明確定義其中一個操作符:

class AddAndSub 
{ 
public: 
    virtual AddAndSub operator +(AddAndSub const & b) 
    { 
    return *self - (-b); 
    } 
    virtual AddAndSub operator -(AddAndSub const & b) 
    { 
    return *self + (-b); 
    } 
} 

但是我對我的解決方案並不完全滿意,因爲我仍然需要定義至少一個操作,但是它沒有被代碼明確強制執行,並且忘記了定義一個導致非常不明確的錯誤消息的結果「堆棧溢出」。我可以像第一個例子中那樣保留接口,以確保每個實現它的類定義了所需的方法,但是這樣會導致非平凡情況下的大量冗餘代碼。

有沒有一種合適的方法來減少這種情況下的代碼冗餘,同時仍然保持編譯時間檢查並將選擇哪些方法實現給接口用戶?

PS:我知道我可以讓這些方法之一純虛擬,但是我不能選擇哪種方法,我可以定義在一個情況下,當實施加法比減法更難(TBH只是一個小挑逗,但我仍然想知道是否有更好的方法)。

+0

備註:設計加運算符對於開放類層次結構的直觀工作很困難。只保留a + b = b + a是一個巨大的挑戰。令人信服的基類正確地添加一些非常派生的類也很有趣.. –

+1

我不會在運行時多態接口中使用這樣的運算符,也就是說。虛擬運營商。這將極大地限制您的代碼的靈活性。在處理算術運算符時考慮使用編譯時多態性和泛型編程。 –

回答

1

最好保持界面純粹抽象。如果你想用operator +()來實現operator-(),反之亦然,那麼在你的實現類中(es)。

如果出於某種原因,您確實想要最大限度地減少您的實現類必須覆蓋的方法數量,請考慮創建一個輔助類,它將接口子類化並按照其他方法實現一些方法。您可以將這些方法標記爲最後的(C++ 11功能)禁止它們再次被您的實現類重寫,這將是繼承類的子類。

+0

幫助程序類看起來像是我的問題的解決方案,但是我希望更像Haskell'Eq',它只需要'=='或'!='來工作。 –

相關問題