【问题标题】:Passing a virtual member method to thread()将虚拟成员方法传递给 thread()
【发布时间】:2014-08-20 18:04:38
【问题描述】:

我正在尝试将虚拟方法传递给线程类的构造函数(C++ 线程)。

翻遍后,我只能传递一个非虚拟成员方法。

我的基类A有一个start方法如下:

void A::start() {
    thread(&A::runnable,A()); // <--- What do I change here?
}

runnable 函数是虚函数,也在派生类B 中实现。 我在派生类 B 中覆盖了 runnable。

然后我在 B 上调用 start

显然,并且不受欢迎的是,start 函数使用在 A(而不是 B)中实现的 runnable,因为它在 A::start 中明确定义。 有没有办法让runnable函数动态绑定?

我想过使用模板和其他一些创造性的解决方案。 (如果没有真正的解决方案,我最终会在 B 中实现 start

任何帮助将不胜感激。

【问题讨论】:

  • 看看std::bind()
  • @πάνταῥεῖ 在这种情况下使用 std::bind 不会改变任何东西。

标签: c++ inheritance


【解决方案1】:

很明显,并且不受欢迎的是,start 函数使用在 A(而不是 B)中实现的 runnable,因为它在 A::start 中明确定义。

这对您来说可能很明显,但它是不正确的。当你创建一个线程时,你传递了一个未命名的类A 的临时实例,它显然具有A 类型,所以总是会调用A::runnable,但你应该传递this

void A::start() {
    thread(&A::runnable,this); // <--- What do I change here?
}

然后会调用适当的虚函数。 详情请参阅Boost::Bind and virtual function overloads: why do they work?

【讨论】:

    【解决方案2】:

    有几件事需要解决。

    首先在A::start() 创建一个匿名本地线程对象。不幸的是,一旦你离开 A::start(),这个对象就会被破坏。这将触发中止。

    当你创建一个线程对象时,你必须在对象被破坏之前要么join()它要么detach()它。

    对于其余的答案,我将在 A 中使用私有线程 t:

    class A {
        ...
    protected:
        thread t;       // default constructed thread object, i.e. without associated  thread of execution 
    public:  
        ...
        ~A() {
            if (t.joinable())   // If thread active and not detached, be sure that it's joined before it is destructed !!
                t.join();
        }
    ....
    };
    

    接下来,在创建线程时,使用A() 作为参数。这意味着您将创建一个新的匿名 A 对象并将其作为参数传递。我想这不是你打算做的,所以你改用this

    然后,正如 Slava 所说,当 &A::runnable 与 this 结合使用时,调用的是虚函数。所以 start() 应该是这样的:

    void start() {
        t = move (thread (&A::runnable, this )) ;  // Here I create an anonymous thread and move it to t.   
    }
    

    如果您运行此代码,您会注意到 A::runnable() 为 A 类对象调用,而 B::runnable() 为 B 类对象调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      • 2020-12-05
      • 2011-03-22
      相关资源
      最近更新 更多