基于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
,因此线程执行{{1}这是纯粹的虚拟
其他问题:是否有任何方式标记Base::operator()
受保护?
有人可以帮帮我吗?感谢。
编辑:
根据Billy ONeal的回答,我重写了代码,因此operator()
构造函数调用了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);
答案 0 :(得分:5)
您的代码存在竞争条件(因此未定义的行为)。当您在Base
的构造函数中启动线程时,线程将立即尝试在该对象上调用operator()
。但是Derived
的构造函数还没有运行,所以operator()
仍然是来自Base
的那个,它是纯虚拟的。另一个有效的执行是Base
的构造函数和Derived
的构造函数在线程实际开始之前完成,这会产生你期望的行为,但结果不太可能。
你对this->run
没有帮助的评论是有道理的,因为输出会抱怨调用纯虚拟成员函数,而run
不是纯虚拟成员,只有operator()
。< / p>