3

抽象基本クラス X を定義し、次のことを強制したいと思います。

a) X から継承するすべての具体的なクラス Y は、コンストラクター Y(int x) を定義します

b) 2 つの Y オブジェクトが等しいかどうかをテストできる必要があります。

aの場合、あまり良くない解決策の1つは、具象クラスが定義する必要がある純粋な仮想fromIntメソッドをXに入れることです。しかし、私は建設を強制することはできません。

b)については、Xで純粋仮想メソッドを使用できないようです

bool operator == (const X& other) const =0;

オーバーライドされたクラスでは、これは未定義のままであるためです。定義するだけでは不十分

bool operator == (const Y& other) const { //stuff}

タイプが合わないからです。これらの問題を解決するにはどうすればよいですか?

4

6 に答える 6

3

引数なしのコンストラクターをプライベートにし、基本クラスに public の単一の int 引数コンストラクターを含めることで、強制的に構築できます。基本クラスにいくつかの純粋仮想メソッドがある限り、サブクラスはそのコンストラクターを呼び出す必要があります。

operator== については

bool operator == (const BaseClass& other) const { .. };

、すべてのサブクラスで定義してみてください。最悪の場合、ベースで純粋な仮想である public equals(const BaseClass& other) メソッドを定義できます。

編集:強制コンストラクターのことは完全に真実ではありません。私が提案したことは、サブクラスが単一の引数コンストラクターを呼び出すことを強制します。コンストラクターのベースまで定数を渡す引数のないコンストラクターを持つことができます。

于 2010-04-13T21:37:18.593 に答える
2

b)の場合virtual bool operator == (const X & other) const = 0、Xで定義できます。

比較のパラメーターとして使用することはできませんがconst Y & other、Yは自動的にXにキャストされ、dynamic_castを使用して、比較できるクラスであるかどうかを確認できます。

于 2010-04-13T21:44:35.190 に答える
2

簡単な解決策があります。

// Class X
// (... some documentation ...)
//
// ** NOTE: All subclasses of X must have a constructor that takes a single int,
// ** and overload operator==.

class X {
 ...
于 2010-04-13T21:49:11.393 に答える
0

a-CRTPと、すべてのユーザーコードが継承する必要のある中間のフレンドのテンプレート化されたサブクラスを使用する場合は可能です。そのようなもの:


struct X 
{
  virtual bool compare(X const&) const = 0;
private:
  X();

  template < typename T >
  friend struct client_base; // don't recall the correct code here.
};


template < typename Sub >
struct client_base : X
{
  // use boost::concepts to verify Sub has Sub(int)
  Sub() : X() {}
};

struct Y : client_base<Y>
{
  Y(int);

  bool compare(X const& x)
  {
    if ((Y* other = dynamic_cast<Y*>(x)) && *other == *this) return true;
    return false;
  }
};

明らかに、これを完全なソリューションにするために、あなたが理解するために多くのことを残しました。

于 2010-04-13T21:39:11.723 に答える
0

a)私には意味がありませんが、何かを作成することはできます

template< typename T >
Base* create( int x )
{
    return T::create( x );
}

b)c++での「マルチメソッド」の実装についてグーグルに尋ねる

于 2010-04-13T21:40:58.230 に答える
0

整数から構築可能であることを強制することは意味がありません。各派生クラスは、必要に応じてコンストラクターを自由に定義できます。ただし、基本クラスに整数を渡すように強制することはできます...とにかくそれがはるかに理にかなっているわけではありません。

operator==もゆがんでいますが、その本質を知ることができます。

class Base
{
public:
  bool operator==(const Base& rhs) const;
  bool operator!=(const Base& rhs) const { return !(*this == rhs); }

private:
  virtual bool equals(const Base& rhs) const = 0; // will pass only objects
                                                  // of the same dynamic type
};

bool Base::operator==(const Base& rhs) const
{
  return typeid(*this) == typeid(rhs) && this->equals(rhs);
}

bool Derived::equals(const Base& rhs) const // We KNOW Base is actually a Derived
{
  return *this == static_cast<const Derived&>(rhs);
}

テンプレートとCRTPを使用して少し見栄えを良くすることもできますが、Derived継承された場合はどうでしょうか。それは成り立たないでしょう。

于 2010-04-14T09:15:29.547 に答える