Как запустить нестатическую функцию в новом потоке в C ++ - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь написать простую игру на C ++.У меня есть класс с именем player с функцией moveLeft (); , которая постоянно отслеживает получение "a", которое я хочу запустить в отдельном потоке.

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

Класс игрока

#pragma once
class player
{
    public:
        player(); // Constructor
        ~player(); // Destructor

        void moveLeft();
        void moveRight();
        void jump(double);

        int getHealth();

        double get_x_position();
        double get_y_position();

        double get_x_momentum();
        double get_y_momentum();

        bool getGrounded();

        void setHealth(int);

        void set_x_position(double);
        void set_y_position(double);

        void set_x_momentum(double);
        void set_y_momentum(double);

        void setGrounded(bool);

    private:
        int health;

        bool grounded;

        double x_position;
        double y_position;

        double x_momentum;
        double y_momentum;
};

Функция moveLeft ()

void player::moveLeft()
{
    while (true)
    {
        while (GetKeyState(97))
        {
            if (grounded)
            {
                x_momentum -= .01;
            }
            else
            {
                x_momentum -= 0.07;
            }

            x_position += x_momentum;
        }
    }
}

Как я думал, я должен был ее настроить.

thread t1(&player::moveLeft);
t1.detach();

Ответы [ 4 ]

0 голосов
/ 12 сентября 2018

С должным уважением - я считаю, что структура вашей программы или общий дизайн неуместны.

  • В методах объектов проблемной области не должно быть обработки событий или операций ввода-вывода.
  • Если существуют ограничения в отношении того, когда происходит движение (например, не двигаться влево, пока что-то не происходит) - почему существуют методы, которые немедленно влияют на движение (например, set_x_position())?
  • Зачем беспокоиться о частных членах, если у вас есть тривиальные геттеры и сеттеры от них? Разве это не тот случай, когда вы действительно должны просто бросить сеттеры?
  • Экземпляр класса проигрывателя является общим для нескольких потоков. Разве вы не должны как-то блокировать его, когда изменяете его в одном из них?

Чтобы ответить на ваш конкретный вопрос, хотя:

auto l = [&]() { player1.moveLeft(); }
auto t1 = std::thread{l};
t1.detach();
0 голосов
/ 12 сентября 2018

Если вы хотите сделать это таким образом, вам нужно создать экземпляр класса игрока

player *myplayer = new player(); //do this in your initializer, not for every call.
thread t1(&player::moveLeft, myplayer);
t1.detach();

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

0 голосов
/ 12 сентября 2018

Вы можете использовать std::bind для решения этой проблемы.

thread t1(std::bind(&player::moveLeft,this));
t1.detach();
0 голосов
/ 12 сентября 2018

Если вы запускаете поток из функции-члена вашего класса, вы, вероятно, ищете

thread t1(&player::moveLeft, this);
t1.detach();

. Причина включения указателя this состоит в том, что каждая функция-член имеет скрытый параметр,указатель на объект, с которым он связан.this в приведенном выше коде является player*.Конечно, вы можете использовать любой другой указатель на player, не обязательно this.На какой бы объект вы ни указывали, функция-член будет видеть его как «этот объект» внутри своего тела.

...