1

可能なカスタマイズのための多くの異なるオプションを備えたクラスライブラリを作成しています。たとえば、FeatureX()を実行できるようにクラスを設計したり、FeatureY()を実行できるようにクラスを設計したりできます。

通常の状況では、FeatureXと呼ばれる純粋仮想メソッドを使用してインターフェイスIFeatureXを作成し、FeatureYと呼ばれる純粋仮想メソッドを使用して別のインターフェイスIFeatureYを作成するだけです。クラスにFeatureXとFeatureYの両方がある場合、問題なく両方から継承できます。

私の問題は、関数/メソッドがFeatureX()とFeatureY()の両方を実行できるオブジェクトを必要とする場合はどうなるでしょうか?できればC++で型を表現するにはどうすればよいですか。ただし、FeatureXとFeatureYの両方を確実に使用できるようにするには、Javaでの回答も役立ちます。

IFeatureXとIFeatureYから継承する別のインターフェイスIFeatureXYを作成しますか?わかりました...機能が2つしかない場合は、これで問題を解決できます。しかし、たとえば10の機能があるとすると、可能なインターフェイスの数は膨大になります。

これを行う簡単な方法はありますか?C ++テンプレートと委任を使用して問題を解決しようとしましたが、それほど遠くはありませんでした。私はこれに対する簡単な解決策があることを望んでいます、そしておそらく私がちょうど見落としたものがあるでしょう。

皆さんの助けとアドバイスに感謝します。

ありがとう。

4

7 に答える 7

2

テンプレートの使用を恐れていない場合は、関数をテンプレートにして、SFINAEを使用して2つのインターフェイスを確認できます。

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トリックは機能する必要がないことに注意してください。制約のないテンプレートは機能しますが、要件を満たさない型を渡すとコンパイルに失敗します。 )。

もう1つの可能性は、両方を拡張するインターフェイスIFeatureXYを作成し、これを関数パラメーターで使用することです。これには、両方のインターフェースを実装するタイプであるが、このジョイントインターフェースを実装しないタイプはこのメソッドでは使用できないという欠点があります。

また、インターフェイスごとに1つずつ、2つの引数を関数に渡すことができ、それらが同じオブジェクトへのポインターである必要があります。これは壊れやすいですが、2つのポインタを保持するテンプレートクラスを作成することで強化できます。product_type<IFeatureX*, IFeatureY*>、これは問題の単一のオブジェクトによって初期化され、2つのタイプを保持します。

Javaでは、おそらく有界型変数で同じことを行うことができます(複数の境界が許可されている場合、今はわかりません)。

于 2009-04-07T21:32:06.333 に答える
1

まったく異なる機能を追加する方法はいくつかありますが、これらの追加機能の範囲について検討することをお勧めします。それらはあなたのメインクラスライブラリに関連していますか? (そうでない場合は、その一部であるべきではないと主張することができます)

機能を追加するのに十分な共通点がある場合は、デコレータ パターン ( http://en.wikipedia.org/wiki/Decorator_pattern ) のようなものを探すことができます。これにより、このようなことを行う際の厄介な問題のいくつかを回避できます。

于 2009-04-07T21:44:37.643 に答える
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();
}

このようにして、オブジェクトにインターフェイスを問い合わせることができます。同様のメソッドが、IUnknown :: QueryInterface()のCOM+で使用されます。

于 2009-04-07T21:38:39.080 に答える
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
于 2009-04-07T21:44:17.817 に答える