次のインターフェイスを実装しました。
_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))
。それを行う方法はありますか?
これは私が何度も実行した問題です。
これは不可能であり、正当な理由がありますが、本質的に同じことを達成する方法があります。個人的に、私は今使用します:
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
そのようなことが可能であったとしても、派生したインスタンス化を基本クラスへのポインターを介して多態的に呼び出すことができなかったため、仮想関数として持つことはもはやあまり意味がありません。
これが可能になるとは思わないでください。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.
私はこれが受け入れられた答えがあることを知っています、しかし私はそれをお勧めしませんが、あなたが望むものを達成するための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の引数タイプを実際の引数タイプと一致させる必要があるため、このメソッドはエラーが発生しやすくなります。
これらのパラメータを受け入れる基本クラスにコールバックのオーバーロードを追加する必要があります。 void *を受け入れる、または生のバイトへのポインタを渡すなど、悪いことをすることも可能です。仮想関数のシグネチャを変更することが有効な唯一のシナリオは、戻り値を元の戻り値とは異なるものにオーバーライドする場合です。 *この。