2011-07-27 35 views
1

我在業餘時間構建了一個相當大的插件驅動應用程序,並且遇到了停止設計缺陷的展示。我的應用程序使用基於策略/特徵的設計,但因爲我使用Qt,所以僅通過MI(而不是模板和MI)完成。其中一些類是純虛擬的,一些類在最終用戶不應該觸及的情況下執行相當重要的功能。C++中的QObject多重繼承和策略/特性設計問題

我的問題是,這些類中的一些需要信號/插槽,因此從QObject派生,沒問題,我可以實際上從它繼承。不過,我的問題是,當我想從一個Qt類派生,然後用一個或多個我的性狀進行擴展,如:

class Sy_abstractGLViewport : public QGLWidget, public Sy_saveable, public Sy_abstractObject 
{ 
    ... 
} 

這裏QGLWidget來繪圖是從繼承自QObject,但不是幾乎,引起歧義的問題。

我已經考慮了一個橋樑模式,例如我的Sy_saveable純虛擬,然後從中導出一個Sy_saveable_imp,它包含實際的實現。然後通過聚合使用我的Sy_abstractGLViewport

這對我來說似乎相當不專業,因爲該應用程序是基於插件的,這對我未來的插件編寫者將所有接口方法「掛接」到聚合實例中有點PITA。我甚至無法通過宏自動化它,因爲最終用戶可能想重寫一個方法。

有沒有人解決這個問題的模式?或者不需要MI的模式,但給了我相同的靈活性?這是我個人的嗜好項目,我不介意做很多重構 - 我想要做right

+1

不知道你是否這樣做,但我不會從QObject幾乎繼承。它在qt 4.7和之前的版本中運行,但可能不會在qt 4.8中運行。請參閱https://bugreports.qt.nokia.com/browse/QTBUG-19717 – masebase

回答

1

您不能從繼承QObject的多重繼承繼承。

嘗試使用組合而不是繼承。見composition over inheritance

您也可以嘗試使用Q3Signal類。雖然它屬於老QT3根據QT DOC:

的Q3Signal類可用於發送信號,對於不 繼承QObject的類。

+0

只要在父類中聲明爲虛擬繼承,您就可以多次從QObject繼承 - 但Qt自己的類不會。組合的問題在於它允許用戶基本上覆蓋不應該的方法(因爲我依賴它們正確地構建訪問器方法),或者簡單地不構建相關訪問器。 – cmannett85

+3

不,您不應該在QObject上使用虛擬繼承(http://doc.qt.nokia.com/latest/moc.html#multiple-inheritance-requires-qobject-to-be-first)。不要這樣做,即使你的代碼編譯,你也會遇到奇怪的行爲。 –

+0

因爲我很懶,因此不喜歡作文,所以我不得不承認這是我唯一的出路。我設法保留我的is_a關係,方法是讓我的舊特徵類接口,然後從它們創建'實現'類,最終用戶從它們的聚合成員派生出來。 – cmannett85