C ++: массив указателей на функции-члены для различных функций - PullRequest
7 голосов
/ 25 августа 2010

У меня есть класс A, который содержит функции-члены foo () и bar (), которые возвращают указатель на класс B. Как я могу объявить массив, содержащий функции foo и bar, как переменную-член в классе A? И как мне вызвать функции через массив?

Ответы [ 2 ]

19 голосов
/ 25 августа 2010

Синтаксис указателя на функцию-член равен ReturnType (Class::*)(ParameterTypes...), например ::

typedef B* (A::*MemFuncPtr)(); // readability
MemFuncPtr mfs[] = { &A::foo, &A::bar }; // declaring and initializing the array
B* bptr1 = (pointerToA->*mfs[0])(); // call A::foo() through pointer to A
B* bptr2 = (instanceOfA.*mfs[0])(); // call A::foo() through instance of A

См. Например эта статья InformIT для более подробной информации об указателях для членов.

Возможно, вы также захотите изучить Boost.Bind и Boost.Function (или их эквиваленты TR1), которые позволяют непрозрачно связывать указатели на функции-члены с экземпляром. :

typedef boost::function<B* ()> BoundMemFunc;
A instanceOfA;
BoundMemFunc mfs[] = { 
    boost::bind(&A::foo, &instanceOfA), 
    boost::bind(&A::bar, &instanceOfA) 
};
B* bptr = mfs[0](); // call A::foo() on instanceOfA

Чтобы использовать такой массив в качестве члена, обратите внимание, что вы не можете инициализировать массивы, используя список инициализаторов членов. Таким образом, вы можете присвоить ему в теле конструктора:

A::A {
    mfs[0] = &A::foo;
}

... или вы используете тип, который на самом деле может быть инициализирован там, например std::vector или boost::array:

struct A {
    const std::vector<MemFuncPtr> mfs;
    // ...
};

namespace {
    std::vector<MemFuncPtr> init_mfs() {
        std::vector<MemFuncPtr> mfs;
        mfs.push_back(&A::foo);
        mfs.push_back(&A::bar);
        return mfs;
    }
}

A::A() : mfs(init_mfs()) {}
2 голосов
/ 25 августа 2010

Вы ищете указатели на функции-члены .Вот короткий пример, который показывает их объявление и использование:

#include <iostream>

class B {
public:
  B(int foo): foo_(foo) {
    std::cout << "Making a B with foo_ = " << foo_ << std::endl;
  }
  ~B(void) {
    std::cout << "Deleting a B with foo_ = " << foo_ << std::endl;
  }
  int foo_;
};

class A {
public:
  A(void) {
    funcs_[0] = &A::foo;
    funcs_[1] = &A::bar;
  }

  B* foo(void) {
    return new B(3);
  }

  B* bar(void) {
    return new B(5);
  }

  // Typedef for the member function pointer, for everyone's sanity.
  typedef B* (A::*BMemFun)(void);
  BMemFun funcs_[2];
};

int main(int argc, char *argv[]) {
  A a;
  for (int i = 0; i < 2; ++i) {
    A::BMemFun func = a.funcs_[i];
    // Call through the member function pointer (the .* operator).
    B* b = (a.*func)();
    delete b;
  }
  return 0;
}

В разделе C ++ FAQ по указателям на функции-члены , где я нашел всю эту информацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...