Как передать функцию-член в качестве параметра и выполнить список методов для производного объекта - PullRequest
0 голосов
/ 21 января 2020

Я хочу создать целочисленные значения отображения массива для функций-членов, чтобы

(this->*actionMap[i])();

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

Я видел в предыдущем вопросе, что он должен использовать std :: function и std :: bind, но я я не следую синтаксису, и я не понимаю, как объявить массив: Как правильно передать функцию-член в качестве параметра

Вот M (не) WE Обратите внимание, что я хочу базовый класс для возможности выполнения методов на производном объекте.

#include <iostream>
using namespace std;
class Base;
typedef void (Base::*Action)();

class Base {
    Action actions[3];
public:
    void setAction(int a, Action act) {
        actions[a] = act;
    }
    void f() { cout << "f"; }
    void go() {
        for (int i = 0;  i < 3; i++)
            (this->*actions[i])();
    }
};

struct Derived : public Base {
    void g() { cout << "g"; }
    void h() { cout << "h"; }
    Derived() {
        setAction(1, f);
        setAction(2, g);
        setAction(1, h);
    }
};

int main() {
    Derived d;
    d.go();
}

1 Ответ

2 голосов
/ 21 января 2020

выполняет методы для производного объекта.

Таким образом, вы должны иметь дескриптор производного объекта при выполнении методов. И два метода не в Base::, потому что они не внутри Base. Они находятся внутри Derived, поэтому указатели могут быть Derived::*, но это не имело бы смысла и нарушало бы модель, которую, я думаю, вы хотите иметь. Я думаю, вы могли бы сделать ваши методы g h и f виртуальными внутри Base. Но это опять же, победив цель, я полагаю, паттерн типа «наблюдатель-я» sh.

То, что вы хотите сделать, в основном легко решается с помощью правильной абстракции - std::function и std::bind .

#include <iostream>
#include <array>
#include <functional>

class Base {
    std::array<std::function<void()>, 3> actions;
public:
    void setAction(int a, std::function<void()> act) {
        actions.at(a) = act;
    }
    void f() { std::cout << "f"; }
    void go() {
        for (auto&& action : actions) {
            if (action) {
                action();
            }  
        }
    }
};

struct Derived : public Base {
    void g() { std::cout << "g"; }
    void h() { std::cout << "h"; }
    Derived() {
        setAction(1, std::bind(&Derived::f, this));
        setAction(2, std::bind(&Derived::g, this));
        setAction(1, std::bind(&Derived::h, this));
    }
};

int main() {
    Derived d;
    d.go();
}
...