添え字演算子のC ++継承規則

マーク

C ++での添え字演算子、オーバーロード、および継承について質問があります。 複数の関数オーバーロードを持つ親クラスがある場合、子が関数の1つだけをオーバーライドして、残りを継承する可能性があると確信しています。同じことが添え字演算子には当てはまらないようです。 (私は悪い仮定をしました。それは他の関数と実際には違いはありません。)次のコードを考えてみましょう。

struct A {};
struct B {};

struct Parent
{
   virtual ~Parent() {}
   virtual int operator[](A index) { return -1; }
   virtual int operator[](B index) { return -2; }
};

struct Child : public Parent
{
   virtual int operator[](B index) override { return -3; }
};

int main()
{
   // error: no match for 'operator[]' (operand types are 'Child' and 'A')
   return Child()[A()]; 
}

エラーを発生させるのではなく、親からの添え字演算子を使用することを期待します。オーバーロードされた添え字演算子を親から継承し、他の演算子をオーバーライドすることは可能ですか?そうでない場合、実行するよりも良い解決策はありますか?

struct Child : public Parent
{
    virtual int operator[](B index) override { return -3; }
    // Force it to use the parent method
    virtual int operator[](A index) override { return Parent::operator[](index); }
};

親から多くの場所を継承する可能性があり、このような機能を手動で指定しなければならないのはメンテナンスにとって悪いことです。あなたのアイデアをありがとう。

クリスチャンハックル

C ++では次の2つのことを避けてください。

  • オーバーロードとオーバーライドの混合。
  • パブリック仮想関数(デストラクタでない場合)。

基本クラスのオーバーロードされた演算子を非仮想のままにし、それらを異なる名前のプライベート仮想関数に委任します。

次に例を示します。

struct A {};
struct B {};

struct Parent
{
   virtual ~Parent() {}
   int operator[](A index) { return withA(index); }
   int operator[](B index) { return withB(index); }
private:
   virtual int withA(A index) { return -1; }
   virtual int withB(B index) { return -2; }
};

struct Child : public Parent
{
private:
   virtual int withB(B index) override { return -3; }
};

int main()
{
   return Child()[A()]; 
}

このアプローチは、非仮想インターフェイスイディオムとも呼ばれ、基本クラスのクライアントと派生クラスの実装者の間の関心の分離を表しています。また、副作用としてコンパイルの問題を解決します。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事