6

では、最初にサンプル コードを示します。これは、コンパイルされませんが、私がやろうとしていることを伝えようとする私の試みです:

#include <iostream>

template <class T>
class Base
{
public:
    virtual void my_callback() = 0;
};

class Derived1
    : public Base<int>
    , public Base<float>
{
public:
    void my_callback<int>()
    {
        cout << "Int callback for Derived1.\n";
    }
    void my_callback<float>()
    {
        cout << "Float callback for Derived\n";
    }
};

class Derived2
    : public Base<int>
    , public Base<float>
{

public:
    void my_callback<int>()
    {
        cout << "Int callback for Derived2.\n";
    }
    void my_callback<float>()
    {
        cout << "Float callback for Derived2\n";
    }

};

int main()
{
    {
        Derived1 d;
        Base<int> * i_p = d;
        Base<float> * i_f = d;

        i_p->my_callback();
        i_f->my_callback();
    }
    {
        Derived2 d;
        Base<int> * i_p = d;
        Base<float> * i_f = d;

        i_p->my_callback();
        i_f->my_callback();
    }

    //Desired output:
    // Int callback for Derived1.
    // Float callback for Derived1
    // Int callback for Derived2.
    // Float callback for Derived2
    system("Pause");
}

だから、私がやろうとしているのは、派生クラスをさまざまなコールバックリストに自動的に接続する一種のラッパークラスを継承することです。派生クラスの特定のインスタンスをリストに接続する必要があります。ご覧のとおり、派生クラスの作成の一環として、「ユーザー」がコールバック関数を作成する必要があります。

別の構文を使用する必要があるかもしれませんが、これは機能するはずです。うまくいかない場合、何か提案はありますか?

4

4 に答える 4

2

あなたが望むことは不可能です。

テンプレートの特殊化を追加できますが、これが本当に役立つかどうかはわかりません。

template <class T>
class Base {
public:
  virtual void my_callback() = 0;
};

template <>
class Base<int> {
public:
  virtual void my_callback() {
    cout << "Base<int>::my_callback()\n";
  }
};

template <>
class Base<float> {
public:
  virtual void my_callback() {
    cout << "Base<float>::my_callback()\n";
  }
};

class Derived1 : public Base<int>, public Base<float> {
public:
  // NOTE: no my_callback() implementation here
};

class Derived2 : public Base<int>, public Base<float> {
public:
  virtual void my_callback() {
    cout << "Derived2::my_callback()\n";
  }
};


int main()
{
  {
    Derived1 d;
    Base<int> * i_p = &d;
    Base<float> * i_f = &d;
    i_p->my_callback();
    i_f->my_callback();
  }
  {
    Derived2 d;
    Base<int> * i_p = &d;
    Base<float> * i_f = &d;
    i_p->my_callback();
    i_f->my_callback();
  }
}

出力:

Base<int>::my_callback()
Base<float>::my_callback()
Derived2::my_callback()
Derived2::my_callback()

理由を説明してみましょう。

Derived1 d;
Base<int> * i_p = &d;
Base<float> * i_f = &d;

// will check the vtable, and will call
//  either Derived1::my_callback
//  OR Base<int>::my_callback
i_p->my_callback();

// will check the vtable, and will call
//  either Derived1::my_callback
//  OR Base<float>::my_callback
i_f->my_callback();

vtableを介してクラスDerived1にはmy_callback()の2つのバージョンがありますが、どちらもオーバーライドできません。両方を一度にオーバーライドすることしかできません(例のDerived2のように)。

「my_callback1()」と「my_callback2()」の2つのメソッドを指定する必要があります。

于 2009-12-13T21:17:23.113 に答える
2

はい、これを機能させることができます:

#include <iostream>
using namespace std;

template <class T>
class Base
{
public:
  virtual void my_callback() = 0;
};

class Derived1 : public Base<int>, public Base<float>
{
public:
  void Base<int>::my_callback() {
    cout << "Int callback for Derived1.\n";
  }
  void Base<float>::my_callback() {
    cout << "Float callback for Derived\n";
  }
};

class Derived2 : public Base<int>, public Base<float>
{
public:
  void Base<int>::my_callback() {
    cout << "Int callback for Derived2.\n";
  }
  void Base<float>::my_callback() {
    cout << "Float callback for Derived2\n";
  }
};

int main()
{
  {
    Derived1 d;
    Base<int> * i_p = &d;
    Base<float> * i_f = &d;
    i_p->my_callback();
    i_f->my_callback();
  }
  {
    Derived2 d;
    Base<int> * i_p = &d;
    Base<float> * i_f = &d;
    i_p->my_callback();
    i_f->my_callback();
  }
}

出力:

Int callback for Derived1.
Float callback for Derived
Int callback for Derived2.
Float callback for Derived2
于 2009-12-13T20:54:36.857 に答える
0

テンプレート クラスまたは非テンプレート クラスを使用するかどうかにかかわらず、これは、このスタイルまたはこのスタイルのヘルパー クラスを使用して実行できます。

(Microsoft 固有の修飾名を使用する予定がない場合、これが唯一のポータブル ソリューションのようです。)

于 2013-03-06T12:35:43.487 に答える
-1

テンプレートに関連付けられた仮想性はあなたの頭の中でアラームを発生させませんか?;)

静的または動的のどちらかを選択する必要があります。

于 2009-12-13T21:19:39.643 に答える