4

例を考えてみましょう。

Aあらゆる種類の算術演算子 ( ) をオーバーロード/実装するコンテナー クラス ( ) がありA::negate()ます。

B派生クラス (および)を作成したいと考えていますC

Bまた、Cすべての演算子が によって実装されている必要がありますA

ただし、これらの演算子は、派生クラス オブジェクトを引数として使用する必要があります。

のプロトタイプは、 の代わりに であるB::negate必要があります。B B::negate()A B::negate()

派生クラスは独自のフィールドを必要としませんが、独自のメソッド ( B::foo()C::bar()) を実装できます。とが非互換である必要がBあります。つまり、オブジェクトをオブジェクトに代入したり、の演算子と一緒に使用したりできません。CBCC

これがサンプルコードです。どのように動作させたいですか:

struct A {
        int val;

        A negate() {
                return A{-val};
        }
};

struct B: A {void foo(){}};
struct C: A {void bar(){}};

int main() {
        B obj0 = {5};
        B obj1 = obj0.negate();
}

これはおそらく標準の継承では不可能であり、C++ 11 ではできないことかもしれないことを理解しているので、できるだけそれに近いものを求めています。

私が思いついた現在の最善の解決策は、継承をまったく使用せず、代わりに基本クラスに整数テンプレート パラメーターを追加し、派生クラスをusing B = A<1>;、として定義し、一部の特殊化 (およびusing C = A<2>;のみ) に対してのみメンバー メソッドを実装することです。A::foo<1>(){}A::bar<2>(){}

ただし、このソリューションには非常に不満があります。

4

3 に答える 3

0

テンプレートを使用したくない場合:

A::negate() を保護します。

B:

struct B : public A
{
   B & negate()
   {
      A:negate();
      return *this
   }
  /// and so on
}

negate は B で定義されているため、A で定義されている negate を完全に隠して、B 実装が呼び出され、A に委譲できるようにします。

A のすべてをユーザーから隠す場合は、B に A を継承するのではなく、A を含める必要があります。(A::negate を再度公開する)

struct B
{
   private:
   A m_a;
  public:
   B & negate()
   {
      m_a.negate();
      return *this
   }
  /// and so on
}
于 2013-11-14T20:11:51.903 に答える