Массив указателя на функцию внутри массива объекта - PullRequest
3 голосов
/ 19 мая 2019

У меня есть класс Ghost, который имеет массив функций.Этот класс Ghost тоже массив.Как мне вызвать функции в основном?Я не могу найти способ вызвать эту функцию.Я видел несколько примеров, но ничего подобного.

class Ghost;

typedef void(Ghost::* Func)();

class Ghost
{
    public:
    Func func;

    public:

    void init() {};
    void running_random() {};
    void running_afraid() {};
    void dead() {};


    Ghost(){
        func = new Func[5];

        func[0] = &Ghost::init;
        func[1] = &Ghost::random;
        func[2] = &Ghost::running_afraid;
        func[4] = &Ghost::dead;
    }

};


int main()
{
    Ghost ph[4];

    ph[0]->*func[0](); //???
    ph[0]->(*func[0]()); //???
    (ph[0]->*func[0])(); //???
}

1 Ответ

0 голосов
/ 19 мая 2019

«У меня есть класс Ghost с массивом функций»

Это не точно.Это не просто функции;они являются указателями на член функций, которые являются отдельными зверями для их собственных.

Что не так в этом коде.

  1. Func func должно быть Func *func;

Как вы это сделали, Func func; объявляет одну переменную указателя на член, и вам явно нужен массивих.

Неправильный оператор доступа к элементу.

Вы используете operator ->*, который следует использовать против указателя на объект, соединенный с указателем на член.Но у вас нет указателя на объект.Учитывая Ghost ph[4];, это означает, что ph[0] это не Ghost*, это Ghost.Поэтому следует использовать operator .*.

Неправильный доступ к func элементу.

Массив, содержащий указатели на элементы, является членом Ghost.Использование операторов доступа участника (operator .* или operator ->*) магическим образом не предоставляет доступ к члену func.Именно там вы и решили хранить эти указатели на функции-члены.Эти операторы не ведут себя как operator . и operator ->

Неправильное соединение объекта и элемента.

При связывании указателя на элемент с конкретным объектом с использованием operator .* (или указателя на объект с использованием operator ->*), полное выражение связи должно быть заключено в круглые скобки, , затем список аргументов должен следовать в своих собственных круглых скобках.Короче говоря, только последний из них имеет смысл (но все еще не работает из-за множества проблем, описанных выше).

ph[0]->*func[0]();
ph[0]->(*func[0]());
(ph[0]->*func[0])(); // closest to correct

Резюме

После всего этогомы можем создать что-то, что действительно будет работать:

#include <iostream>

class Ghost;
typedef void(Ghost::*Func)();

class Ghost
{
public:
    Func* func;

public:

    void init() {std::cout << "here!!\n"; };
    void running_random() {};
    void running_afraid() {};
    void dead() {};

    Ghost(){
        func = new Func[5];

        func[0] = &Ghost::init;
        func[1] = &Ghost::running_random;
        func[2] = &Ghost::running_afraid;
        func[4] = &Ghost::dead;
    }
};


int main()
{
    Ghost ph[4];

    (ph[0].*ph[0].func[0])();
}

Вывод

here!!

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

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