2009-04-07 46 views
1

我正在創建一個類庫,其中包含許多不同的選項以實現可能的自定義。例如,您可以設計自己的類,以便它可以執行FeatureX(),或者您可以設計自己的類,以便它可以執行FeatureY()。C++/Java繼承與授權與對等

在正常情況下,你會簡單地創建一個名爲FeatureX純虛方法,並與所謂FeatureY純虛方法的另一個接口IFeatureY接口IFeatureX。如果一個類同時擁有FeatureX和FeatureY,它可以同時繼承,沒問題。

我的問題是,如果一個函數/方法需要能夠同時執行FeatureX()和FeatureY()的對象?我如何用C++表達類型,但是Java中的答案也可以幫助確保FeatureX和FeatureY都可用?

難道我創建一個從IFeatureX和IFeatureY繼承了另一個接口IFeatureXY?好吧...如果只有兩個特點,我可以逃脫這一點。但是,如果說... 10個功能,可能的接口數量變得很大。

有沒有簡單的方法來做到這一點?我試着用C++模板和委託來解決問題,但並沒有太多。我希望有一個簡單的解決方案,可能有一個我只是忽略了。

我很感謝你們的幫助和建議。

感謝。

回答

2

如果你不害怕使用模板,你可以讓你的函數模板,並使用SFINAE檢查這兩個接口:

template <class T> 
void my_function(const T& data, typename enable_if_c< 
    is_convertible<T*, IFeatureX*>::value && 
    is_convertible<T*, IFeatureY*>::value>::type*=0) { 
    ... 
} 

這將創建一個方法,爲每一個同時擴展功能類型接口(請注意,SFINAE技巧不需要它的工作;一個不受約束的模板可以工作,但是當你傳遞一個不符合要求的類型時,編譯失敗)。

另一種可能性是創建一個接口IFeatureXY擴展兩個,並在函數參數中使用它;這有缺點,類型執行這兩個接口,但不是這個聯合接口不能使用這種方法。此外,您可以將兩個參數傳遞給該函數,每個接口一個,並且要求它們是指向同一個對象的指針;這是脆弱的,但可以通過使一些模板類來保存兩個指針來加強 - 例如。 product_type<IFeatureX*, IFeatureY*>,它將由有問題的單個對象進行初始化,並將保存這兩種類型。在Java中,你可以用有界的類型變量來做同樣的事情(如果它們允許多個邊界;我現在不確定)。

+0

謝謝,這與我的想法類似,但看起來更加健壯。 – Kranar 2009-04-08 03:53:00

2

首先要做的是問,如果你試圖做一些事情,不能簡單地表示,如果是的話,問自己是否真的值得做?

既然你不能找到你想要的東西,你會需要考慮的選項之間的依賴關係的一個簡單的模型。如果可以獨立地使用特徵量y的特徵X,則使它們獨立的接口或純虛類

如果不能獨立地使用它們,使一類包括(作爲適當的語言。);問自己爲什麼要將FeatureX和FeatureY作爲單獨的界面,因爲這種使用模式表明他們畢竟不是獨立的。

0

如果你想在C++中做到這一點,那麼多重繼承呢?

0

可能你的粒度太細了。考慮一個數字類 - 您可以執行乘法,除法,加法,減法等操作。但是,您不會爲這些操作中的每一個創建單獨的接口 - 您將創建一個名爲SupportsArithmetic(或其他)的接口來覆蓋它們。

0

WCF有非常好的模式如何確定某些對象是否支持使用IExtensionCollection<T>.Find<E>()的某些接口(或類)。 IExtensionCollection

IFeatureX feature = argument.Find<IFeatureX>(); 

if (feature != null) 
{ 
    // Find() returned an instance so there is an implementation 
    // of IFeatureX available 

    feature.FeatureX(); 
} 

這樣你可以查詢你的對象的一些接口。在COM + IUnknown::QueryInterface()中使用了類似的方法。

0

爲什麼你需要接口?使用模板:

template< typename T > 
void some_function(const T& t) 
{ 
    // use featureX functions 
    t.fetatureX(); 

    // use featureY functions 
    t.featureY(); 
} 

用法:

SomeClass x; // object with only X feature 
some_function(x); // compile time error, because featureY() doesn't exists 
1

雖然有很多方法可以增加完全不同的功能,你可能要考慮一下這些新增的功能範圍。他們將與你的主要類庫有關嗎? (可以爭辯,如果他們不是他們不應該成爲它的一部分)

如果他們有足夠的共同點來保證添加功能,你可以尋找像裝飾模式(http://en.wikipedia.org/wiki/Decorator_pattern)。它可以讓你繞着這樣的事情繞過一些奇怪的問題。