如何使用C++ 11线程与实例方法?

Azu*_*hen 7 c++ c++11

我有一个类播放器,一些子类Player1,Player2,Player3使用C++扩展播放器.
Class Player有一个方法"run",所有Player1,2,3都会覆盖"run"来做不同的事情.

class Player {
public:
    virtual void run();
}
class Player1: public Player {
public:
    void run();
}
Run Code Online (Sandbox Code Playgroud)

在"main"函数中,我将创建一些Player1,2,3的实例
和一些C++ 11线程调用方法"run"这些实例.

int main() {
    Player1 player1;
    Player2 player2;
    Player3 player3;
    Thread thread1(player1.run, this);
    Thread thread2(player2.run, this);
    Thread thread3(player3.run, this);
    thread1.join();
    thread2.join();
    thread3.join();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我试过,我知道它不起作用,
所以我尝试使用另一个函数来调用实例方法.

function doRun1(Player1 player){
    player.run();
}

int main() {
    Player1 player1;
    Player2 player2;
    Player3 player3;
    Thread thread1(doRun1, player1);
    Thread thread2(doRun2, player2);
    Thread thread3(doRun3, player3);
    thread1.join();
    thread2.join();
    thread3.join();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这种方式似乎解决了问题,但我必须创建doRun1,doRun2,doRun3 ....很多函数,
因为doRun1,2,3的参数需要声明哪个是Player1,2或3

我想不到任何更好的解决方案,有人可以帮助我@@?

Wag*_*ota 12

你正在寻找这样的东西......

class Player {
public:
    virtual void run() = 0;
};

class Player1: public Player {
public:
    void run(); // you must implement then for Player1, 2, 3
};

void doRun(Player * player)
{
    player->run();
}

int main(int argc, char * argv[]) {
    Player1 player1;
    Player2 player2;
    Player3 player3;

    thread thread1(doRun, &player1);
    thread thread2(doRun, &player2);
    thread thread3(doRun, &player3);

    thread1.join();
    thread2.join();
    thread3.join();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您愿意,还可以使用lambda表达式:

int main(int argc, char * argv[]) {
    Player1 player1;
    Player2 player2;
    Player3 player3;

    thread thread1([&] (Player * player) { player->run(); }, &player1);
    thread thread2([&] (Player * player) { player->run(); }, &player2);
    thread thread3([&] (Player * player) { player->run(); }, &player3);

    thread1.join();
    thread2.join();
    thread3.join();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

或者,遵循DyP建议:

int main(int argc, char * argv[]) {
    Player1 player1;
    Player2 player2;
    Player3 player3;

    thread thread1(&Player::run, player1);
    thread thread2(&Player::run, player2);
    thread thread3(&Player::run, player3);

    thread1.join();
    thread2.join();
    thread3.join();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,线程将运行在'player1`,`player2`,`player3`的*副本*上.如果需要引用语义,`std :: reference_wrappers`是一个不错的选择(传递`std :: ref(player1)`等).另外,`main`应该返回`int`. (4认同)
  • 为什么不只是`thread thread1(&Player :: run,player1);`?(指向虚拟成员函数的指针仍允许动态调度.) (3认同)
  • 请注意最后一个例子,因为它正在获取参数的副本,这意味着每个新线程都会获取每个玩家子类对象的副本.这可能是也可能不是所期望的. (3认同)