基于C++ polymorphism with variadic function parameter,我尝试编写类似的(非模板,带构造函数)程序

代码:

#include <thread>
#include <iostream>
#include <vector>

class Base
{
public:
    Base (int count) { run(count); } // this-> does not help

    virtual void run (int count) { // non-virtual does not help eighter
        for (int i=0; i<count; ++i)
            threads.emplace_back(std::ref(*this));
    }

    virtual ~Base () {
        for (auto& t : threads)
            t.join();
    }

    virtual void operator() () = 0;

protected:
    std::vector< std::thread > threads;
};


class Derived : public Base
{
public:
    using Base::Base;
    virtual void operator() () { std::cout << "d"; }
};


int main()
{
    Derived d(4);
    std::cout << std::endl;
    return 0;
}

预期结果:
dddd

实际结果(Ubuntu 14.04,gcc v4.8.2):
pure virtual method called
pure virtual method called
terminate called without an active exception
terminate called without an active exception
dAborted (core dumped)

请注意,Derived::operator()至少曾经真正被调用过(最后一行的d,几乎总是这样)。

即使代码非常简单,并且几乎与原始代码相同(请参见上面的链接),它也无法正常工作。我花了数小时来解决这个问题。

目标是构造具有多个线程的Derived。此数量的线程将被执行(在构造函数中)并在析构函数中加入。 operator()应该用作线程主体函数(与原始代码一样)。此外,它应该是虚拟的,以提供多态性。

就我而言,run通过*this(出于某种原因)传递为Base,而不是Derived,所以线程执行了纯虚拟的Base::operator()

附加问题:标签operator()有什么保护的方法吗?

有人可以帮我吗?谢谢。

编辑:

根据Billy ONeal的回答,我重新编写了代码,因此Derived构造函数调用了run,但没有成功
#include <thread>
#include <iostream>
#include <vector>

class Base
{
public:
    virtual void run (int count) { // non-virtual does not help eighter
        for (int i=0; i<count; ++i)
            threads.emplace_back(std::ref(*this));
    }

    virtual ~Base () {
        for (auto& t : threads)
            t.join();
    }

    virtual void operator() () = 0;

protected:
    std::vector< std::thread > threads;
};


class Derived : public Base
{
public:
    Derived (int count) { run(count); }
    virtual void operator() () { std::cout << "d"; }
};


int main()
{
    Derived d(4);
    std::cout << std::endl;
    return 0;
}

结果随时间而变化-这是我所拥有的全部
1) d
2) dd
3) ddd
4) dddd
5) d
    pure virtual method called
    terminate called without an active exception
    ddAborted (core dumped)

特别是5)我无法解释。

我在{...}周围添加了Derived d(4);作为匿名块,以在行结束程序终止之前强制执行析构函数,但是从那以后,我只有
pure virtual method called
terminate called without an active exception
ddAborted (core dumped)

最佳答案

您的代码具有竞争条件(因此有未定义的行为)。当您在Base的构造函数中启动线程时,该线程将立即尝试在该对象上调用operator()。但是Derived的构造函数尚未运行,因此operator()仍然是Base的构造函数,后者是纯虚拟的。另一个有效的执行方式是Base的构造函数和Derived的构造函数在线程实际运行之前完成,这将提供您所期望的行为,但是结果不太可能。

您对this->run的评论无济于事,因为输出提示调用了纯虚拟成员函数,并且run不是纯虚拟成员,只有operator()是。

关于c++ - 使用std::thread时c++ 11意外的多态行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23434201/

10-11 22:33
查看更多