7

C ++でインターフェース(抽象クラ​​ス)を使用して、インターフェースを継承するクラスよりも強制的に演算子==を実装する必要があります。この状況を考慮してください:

class IBase
{
   virtual void someFunc() const = 0; 
}

class CInheritClass : public IBase
{
   virtual void someFunc() const; 
   virtual bool operator== ( const CInheritClass& obj ) const;
}

void main()
{
  CInheritClass instance;
}

クラス CInheritClass は、Ibase を継承するため someFunc を実装する必要があります。実装virtual bool operator== ( const CInheritClass& obj ) const;は必須ではありません。継承者 X が実装する必要がある方法で IBase クラスを変更したい

virtual bool operator== ( const X& obj ) const

次のコードが機能します。

template<class X>
class IBase
{
   virtual void someFunc() const = 0; 
   virtual bool operator== ( const X& obj ) const = 0;

}

class CInheritClass : public IBase<CInheritClass>
{
   virtual void someFunc() const; 
   virtual bool operator== ( const CInheritClass& obj ) const;
}

しかし、私はテンプレートを使用しないソリューションを求めています.IBaseを実装したいすべてのクラスは、それ自体をテンプレートクラスとしてIBaseを継承する必要がありclass X : public IBase<X>ます. 何か案が ?

4

3 に答える 3

7

純粋仮想関数宣言を使用する

virtual bool operator== ( const IBase& obj ) const = 0;

実装例:

bool CInheritClass ::operator==( const IBase& obj ) const
{
     const CInheritClass *o = dynamic_cast<const CInheritClass*>(&obj);
     if (o == NULL) return false;
     // TODO
}

入力タイプは基本クラスである必要があります。そうでない場合、基本オブジェクトで多態的に呼び出し比較を行うことはできません。

テンプレートから継承するという考えの場合:警告、基本クラスは2つの派生クラス間で同じではなくなりました。=>基本クラスの目的が変更されました:テンプレートを使用すると、コードを共有するだけで、ユーザーに関数を実装させ、2つの派生クラス間でコードが重複しないようにすることができます

それは本当にあなたがやろうとしていることに依存します。それは良いデザインかもしれないし、そうでないかもしれない...

于 2013-01-01T15:39:50.020 に答える
4

参考までに、テンプレート バージョンは一般に「Barton-Nackman トリック」と呼ばれます: http://en.wikipedia.org/wiki/Barton%E2%80%93Nackman_trick

派生クラスを独自の型の (抽象基本型ではなく) 他のオブジェクトとのみ比較したい場合は、それが使用する「トリック」、IMO です。

編集: これは、Java が Comparable インターフェースを実装する方法に似ているため、(優れた) プログラマーが何が起こっているのかを知らないわけではありません: http://docs.oracle.com/javase/7/docs/api/ java/lang/Comparable.html

于 2014-03-21T19:48:19.767 に答える
1

ここで求めているものを分解してみましょう。各子にoperator==、独自の型の右側で を強制的に実装したいとします。しかし、あなたはまた、そのオペレーターを仮想化するよう求めています。各子演算子のパラメーターの型は親仮想メソッドのパラメーター型とは異なるため、基本クラスの演算子を非表示にするだけで終わります。したがって、それをポリモーフィックに呼び出すことはできず、比較の仮想性はまったく役に立ちません。

代わりに、親オペレーターの仮想性を取り除き、子クラスを操作するときに必要な場所を使用することをお勧めします。==次に、コンパイラーは、それが欠落しているときに通知します。

ただし、実際にベースオブジェクトで比較をポリモーフィックに呼び出すことができる必要がある場合は、ダブルディスパッチなどを使用して、両側が最も派生した型にアクセスし、最も派生した型が同じであることを確認する必要があります。 (それ以外の場合、比較は無意味です)。

編集:その機能が本当に必要な場合、テンプレート基本クラスに特に問題はありません。設計を調べて、それが必要であることを確認してください。

于 2013-01-01T15:46:38.797 に答える