1

C++ でメソッド ポインターの配列を作成するにはどうすればよいですか?

問題は、これらのメソッドのシグネチャは同じですが、クラスが異なることです。これらのクラスは、1 つの同じクラスから継承します。

例えば:

class A : public Base {
    virtual bool work();
}

class B : public Base {
    virtual bool work();
}

また、メソッド A::work および B::work へのポインタの配列を別のクラスに作成する必要があります。

編集1:

Useless の提案、オプション 1 を使用することにしました。

vector<Base*> units;
Base *a = new A();
Base *b = new B();
units.push_back(a);
units.push_back(b);

ありがとう

4

4 に答える 4

5

最初のオプション:

異なるメソッドが、異なるサブクラスの同じ仮想メソッドの単なる実装である場合。Base次のようになります。

class Base {
public:
    virtual bool work() = 0;
}

次に、すべてのメソッド ポインターに type がありますbool (Base::*)()。この場合、問題はこのメソッドを呼び出すオブジェクトBase*を選択することなので、さまざまな動的型を持つポインターのコンテナーがあると思われます。


2 番目のオプション:

bool (*)()あなたのクラスは本当に無関係で、オブジェクトを気にせずに署名付きの関数を呼び出したいだけです.

この場合、次のいずれかです。

  1. クラスとそのインスタンスは実際には無関係であり、静的メソッドを使用できます
    • 無料の関数を使用するだけです
  2. インスタンスが必要が、関数を選択するときにその型がわからない

    • インスタンスをキャプチャできるファンクターが必要であり、互換性のある nullary 呼び出し演算子を提供します。すでに提案されているようにstd::function<bool()>、最も簡単な方法です。たとえば、次のようにベクトルを設定できます。

      std::vector<std::function<bool()>> fvec() {
          A a;
          B b;
          std::vector<std::function<bool()>> funcs;
          funcs.push_back( [a]() { return a.work(); } );
          funcs.push_back( [b]() { return b.work(); } );
          return funcs;
      }
      

      abオブジェクトはラムダの値によってキャプチャされるAため、とBが何らかの種類の継承関係を持っているかどうかはもはや問題ではないことに注意してください。

于 2013-05-28T16:55:05.183 に答える
4

std::functionの配列 (std::vector) を作成します

std::bindstd::functionを使用して、任意のメンバー関数への関数ポインターを作成できます。メンバー関数の場合、オブジェクトの特定のインスタンスにもバインドする必要があります。

使用方法の例を次に示します。 std::関数からメンバー関数へ

C++11 にアクセスできない場合は、 と で同じことができますboost::bindboost::function

于 2013-05-28T16:42:58.170 に答える
2

std::functionにあるとのstd::bind両方を組み合わせて使用​​できます<functional>

例:

#include <functional>
#include <vector>

class Base
{
public:
    virtual bool work() = 0;
};

class A : public Base
{
public:
    bool work() {return true;}
};

class B : public Base
{
public:
    bool work() {return false;}
};

int main()
{
    std::vector<std::function<bool(void)>> list;

    A t1;
    B t2;

    list.push_back(std::bind(&A::work, t1));
    list.push_back(std::bind(&B::work, t2));

    for (auto& i : list)
    {
        printf("%s\n", (i()) ? "true" : "false");
    }
}

出力:

true
false
于 2013-05-28T16:45:01.157 に答える
1

技術的には、メンバー関数へのポインターの配列を作成できますが、他の人が示唆しているように、おそらくそうすべきではありません。これは機能します:

class Base {
    public:
    bool work()
    {
        return true;
    }
};

int main()
{
    bool (Base::*arr[2])() = { &Base::work, &Base::work };
    return 0;
}
于 2013-05-28T16:53:45.420 に答える