0

私は次の簡単なクラスを持っています

class base
{
public:
  int x;
  base &set(int y)
    {
      x = y;
      return *this;
    }
};

値xを出力するなど、機能が追加された新しいものを作成したい。私もです:

class derived : public base
{
public:
  void print()
    {
      cout << x << endl;
    }
};

今メインプログラムで私は次のようなことをしたいです

D.set(2).print();

ただし、コンパイラは、クラスベースに「print」という名前のメンバーがないと文句を言います。

共変リターンタイプを使用して、2つのクラスを次のように記述しようとすると

class base
{
public:
  int x;
  virtual base &set(int y)
    {
      x = y;
      return *this;
    }
};

class derived : public base
{
public:
  derived &set(int y)
    {
      x = y;
      return *this;
    }
  void print()
    {
      cout << x << endl;
    }
};

その場合、ステートメントは問題なく機能しますが、変更されるのはreturn型だけですが、両方のクラスの'set'に対してまったく同じ関数本体を書き直す必要がありました。

後でbase::setの機能を変更する必要がある場合は、すべての派生クラスを調べて「set」関数を変更する必要があります...それを回避する方法はありますか?前もって感謝します!

4

2 に答える 2

2

状況によっては、 CRTPを使用できる場合があります。

template <class D>
class base {
    D& set(int x) {
        …;
        return *static_cast<D*>(this);
    }
};

class derived : base<derived> { … };
于 2012-10-11T23:58:37.257 に答える
1

C ++はあなたが言うように動作し、基本クラスでsetreturnと言うbase&ので、それがC++が行うことです。しかし、これを解決するには多くの方法があります。

まずvirtual、派生クラスで関数をオーバーライドする必要はありません(仮想呼び出しは通常の呼び出しよりもわずかに遅いことに注意してください)。

次に、基本クラスの実装を参照しbase::setて、コードを次のようにすることができます。

class base {
    ...
    base& set( int x ) {...}
};
class derived : public base {
    derived& set( int x ) {
        return static_cast<derived&>( base::set(x) );
    }
};
于 2012-10-11T23:43:49.520 に答える