web-dev-qa-db-ja.com

純粋仮想関数のパラメーターの数をオーバーライドします

次のインターフェイスを実装しました。

_template <typename T>
class Variable
{
public:
  Variable (T v) : m_value (v) {}
  virtual void Callback () = 0;
private:
  T m_value;
};
_

適切な派生クラスは次のように定義されます。

_class Derived : public Variable<int>
{
public:
  Derived (int v) : Variable<int> (v) {}
  void Callback () {}
};
_

ただし、Callbackが異なるパラメーターを受け入れるクラスを派生させたいと思います(例:void Callback (int a, int b))。それを行う方法はありますか?

19
Jir

これは私が何度も実行した問題です。

これは不可能であり、正当な理由がありますが、本質的に同じことを達成する方法があります。個人的に、私は今使用します:

struct Base
{
  virtual void execute() = 0;
  virtual ~Base {}
};

class Derived: public Base
{
public:
  Derived(int a, int b): mA(a), mB(b), mR(0) {}

  int getResult() const { return mR; }

  virtual void execute() { mR = mA + mB; }

private:
  int mA, mB, mR;
};

動作中:

int main(int argc, char* argv[])
{
  std::unique_ptr<Base> derived(new Derived(1,2));
  derived->execute();
  return 0;
} // main
16
Matthieu M.

そのようなことが可能であったとしても、派生したインスタンス化を基本クラスへのポインターを介して多態的に呼び出すことができなかったため、仮想関数として持つことはもはやあまり意味がありません。

10

これが可能になるとは思わないでください。Variableにインターフェースを戻すことはできないからです。これは私が意味することです

int a=0; int b = 0;
Variable<int>* derived = new Derived();
derived->Callback(a, b); //this won't compile because Variable<int> does not have Callback with 2 vars.
4
RvdK

私はこれが受け入れられた答えがあることを知っています、しかし私はそれをお勧めしませんが、あなたが望むものを達成するための1つの(醜い)方法があります:

template <typename T> 
class Variable 
{ 
public: 
  Variable (T v) : m_value (v) {}
  virtual void Callback (const char *values, ...) = 0; 

private: 
  T m_value; 
};

class Derived : public Variable<int> 
{ 
public: 
  Derived (int v) : Variable<int> (v) {} 
  virtual void Callback (const char *values, ...) {
  } 
};  

今、あなたは使用することができます:

  int a=0; 
  double b = 0; 
  Variable<int>* derived = new Derived(3); 
  derived->Callback("");
  derived->Callback("df", a, b);

メソッド内の残りの引数を取得するには、values引数が必要です。また、引数の型を知って、printfのように渡す必要があります。

valuesの引数タイプを実際の引数タイプと一致させる必要があるため、このメソッドはエラーが発生しやすくなります。

2
J. Calleja

これらのパラメータを受け入れる基本クラスにコールバックのオーバーロードを追加する必要があります。 void *を受け入れる、または生のバイトへのポインタを渡すなど、悪いことをすることも可能です。仮想関数のシグネチャを変更することが有効な唯一のシナリオは、戻り値を元の戻り値とは異なるものにオーバーライドする場合です。 *この。

1
Puppy