簡體   English   中英

C ++ / Java繼承與委派與等等

[英]C++/Java Inheritance vs. Delegation vs. etc

我正在創建一個類庫,其中包含許多可能的自定義選項。 例如,您可以設計您的類,使其可以執行FeatureX(),或者您可以設計您的類,使其可以執行FeatureY()。

在正常情況下,您只需使用稱為FeatureX的純虛擬方法創建接口IFeatureX,並使用稱為FeatureY的純虛擬方法創建另一個接口IFeatureY。 如果一個類同時具有FeatureX和FeatureY,則可以同時繼承兩者。

我的問題是,如果一個函數/方法需要一個可以同時執行FeatureX()和FeatureY()的對象怎么辦? 如何最好用C ++表示類型,但是用Java回答也可以幫助確保FeatureX和FeatureY都可用?

是否創建另一個繼承自IFeatureX和IFeatureY的接口IFeatureXY? 好的...如果只有兩個功能,我可以解決。 但是,如果說... 10個功能,則可能的接口數量將變得龐大。

有沒有簡單的方法可以做到這一點? 我嘗試使用C ++模板和委派來解決問題,但步步未定。 我希望對此有一個簡單的解決方案,也許我只是忽略了一個。

感謝您提供的任何幫助和建議。

謝謝。

首先要做的是詢問您是否正在嘗試做一些無法簡單表達的事情,如果是,請問問自己是否真的值得做?

鑒於找不到所需的簡單模型,您將需要考慮選項之間的依賴關系。 如果可以獨立於功能Y使用功能X,則使它們成為獨立的接口或純虛擬類(視語言而定)。

如果您不能單獨使用它們,請創建一個包含兩者的類。 問問自己自己為什么要將FeatureX和FeatureY作為單獨的接口,因為這種使用模式表明它們畢竟不是獨立的。

如果您不擔心使用模板,則可以將函數設為模板,並使用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中,您可能會對有界類型變量做同樣的事情(如果它們允許多個界限;我現在不確定)。

盡管有多種方法可以添加完全不同的功能,但是您可能需要考慮這些添加功能的范圍。 它們將與您的主類庫相關嗎? (一個人可能會爭辯說,如果不是,那么就不應成為其中的一部分)

如果它們有足夠的共同點來保證添加功能,則可以尋找諸如裝飾器模式( http://en.wikipedia.org/wiki/Decorator_pattern )之類的東西。 通過這種方式,您可以繞開一些棘手的問題。

如果您想用C ++做到這一點,那么多重繼承又如何呢?

可能您的粒度太細了。 考慮一個數字類-您可以執行乘法,除法,加法,減法等。但是,您不會為這些操作中的每一個創建單獨的接口-您將創建一個稱為SupportsArithmetic的接口(或涵蓋所有內容)。

WCF具有非常好的模式,該模式如何使用IExtensionCollection<T>.Find<E>()確定某些對象是否支持某些接口(或類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();
}

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

為什么需要接口? 使用模板:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM