1

一般的なデザインの質問があります。私はこのようなものを実装しようとしています:

                  ------------
                  |Base Class|
                  ------------
                       |
               ------------------
               |                |
          -----------      -----------
          |SubClass1|      |SubClass2|
          -----------      -----------
               |                |
         --------------   --------------
         |SubSubClass1|   |SubSubClass2|
         --------------   --------------

基本クラスは仮想関数を提供し、サブクラスは実装を提供し、サブサブクラスは実装に定数を提供します。

次のように「Curiously Recurring Template Pattern」を 2 回使用することを考えました。

// header baseclass.h
template <typename subclass>
class baseclass {
private:

public:

  virtual double GetQuantity1(double given1, double given2) = 0;

  virtual double GetQuantity2(double given1) = 0; 

}

// header subclass1.h
template <typename n>
class subclass1:public baseclass<subclass>{
private:

  private1(double, double);

public:

  double GetQuantity1(double given1, double given2);

  double GetQuantity2(double given1); 

}

// header subsubclass1.h
class subsubclass1:public subclass1<subsubclass1>{
private:

public:

  double constant1;

  double constant2;
}

次に、コードを使用するときに Subsubclass::GetQuantity1() を呼び出します。

コーシャのようなものですか、それともこのようなことを行うためのより良い方法はありますか?

よろしくお願いします。

4

1 に答える 1

3

そうすることは問題ありません。これを行うことの一般的な欠点は見当たりません。CRTPを実際に使用している場所と、ユースケースで単純な仮想継承が機能しない理由がわかりません(CRTPは通常、静的ポリモーフィズムとして使用されます)。

また、あなたが何を意味するのか理解できません

private1(double, double);

あなたsubclass1はコンストラクタを意味しましたか?現状では、インスタンス化されたときにコンパイルされません (関数は、コンストラクターまたはデストラクター以外の戻り値なしでは許可されません)。

別の批評家は次のようになります。定数を意味する場合は、サブサブクラスで宣言constまたはstatic constメンバーにする必要があります。

特定のユースケースを明確に指定していないため、実際に最適な設計とは言えません。あなたの考えに従おうとすることから把握した代替案を提供することができます:

// header baseclass.h
template <typename subclass>
class baseclass {
public:

    inline double GetQuantity1(double given1, double given2) {
        // may be add a static check for GetQuantity1_Impl with a traits 
        // check on subclass.
        return static_cast<subclass*>(this)->GetQuantity1_Impl(given1,given2);
    }

    inline double GetQuantity2(double given1) {
        return static_cast<subclass*>(this)->GetQuantity2_Impl(given1);
    }

    // You also can provide default implementations, otherwise the interface
    // method will be required from subclass to compile correctly
    inline double GetQuantity1_Impl(double given1, double given2) {
        // ...
    }
};

// header subclass1.h
template<double const1, double const2>
class subclass1:public baseclass<subclass1>{
public:
    subclass1() {}

    double GetQuantity1_Impl(double given1, double given2) {
        return 0.0; // Apply formula using the constants instead of 0.0
    }
    double GetQuantity2_Impl(double given1) {
        return 0.0; // Apply formula using the constants instead of 0.0
    }
};

// Client implementation file
// No need for subsubclass1 just instantiate for usage

subclass1<0.3, 3.1415> myAlgo;
// A client calls the public interface of the (implicit) base class
double result1 = myAlgo.GetQuantity1(23.2,42);
double result2 = myAlgo.GetQuantity2(2.71828);

subclass基本クラスの純粋仮想メソッド定義を削除し、テンプレート パラメーターの静的インターフェイス (「特性」) チェックに置き換えます。

于 2012-12-25T00:22:41.767 に答える