为什么没有从线程调用重载的成员?

时间:2012-04-10 15:10:40

标签: c++ multithreading pure-virtual

我在Linux Self Help网站上复制了一个稍微修改过的版本,我用它来创建一个线程基类:

class Thread
{
public:
static void *entry (void *pvArg) { Thread *pobjThread = static_cast<Thread *> (pvArg); pobjThread->run (); }
virtual void run (void) = 0;
};

我有2个线程类:

class Item : public Thread

class Product : public Thread

class Item从函数的构造函数启动线程,该类进入pthread库以创建调用entry的线程this作为pvArg而{{1}稍后在程序执行期间创建它的线程。

现在问题是,class Product工作正常。 class Item函数被调用并正确处理。但是,当run稍后调用相同的函数时,我得到:

class Product

两个类都有相同的实现,重载了pure virtual method called 方法,但是一个被调用而另一个没有。

为什么我会突然获得run例外?

感谢。

更新: pure virtual method calledclass Item不同,因为class Product在cpp文件中被声明为Item,并且只有一个。 static Item item;与普通对象一样使用。如果我对class Product执行相同的操作,则可以正常工作。

3 个答案:

答案 0 :(得分:1)

不要从构造函数或析构函数中调用虚函数 - 当代码在其中运行时,继承链是不完整的,因此,调用虚函数没有任何有意义的方法。有关其他答案,请参阅Pure virtual invocation from constructor and destructor

答案 1 :(得分:0)

Item和Product是:public Thread意味着你可以在构造函数中调用一个虚函数(自身)。在构造函数内部,vtable尚未完全设置(因为它依赖于正在初始化的每个基类),因此您将获得未定义的行为。

最佳实践:不要在构造函数/析构函数中调用虚函数。保持构造函数/析构函数非常简单,在init()函数中执行其余的工作等。

答案 2 :(得分:0)

感谢modelnine所指出的,我们发现有问题的代码是在线程有机会运行之前创建一个对象,启动线程然后销毁对象。正如模型所示,这是删除vtable,这导致了问题。

感谢问题评论中的modelnine。