0

我有一个稍微修改过的线程类版本,它是从我用来创建线程基类的Linux 自助站点上复制的:

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 库以创建线程调用entrythis因为pvArgwhileclass Product稍后在程序执行期间创建它的线程。

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

pure virtual method called

两个类都具有相同的实现,都重载了run方法,但是一个被调用而另一个未被调用。

为什么我会突然得到一个pure virtual method called例外?

谢谢。

更新: class Item是不同的,class Product因为在 cpp 文件中Item被声明为 astatic Item item;并且只有一个。class Product像普通对象一样使用。如果我对它做同样的事情,class Product它就可以正常工作。

4

3 回答 3

1

不要从构造函数或析构函数调用虚函数——代码在其中运行时继承链是不完整的,因此,调用虚函数没有意义。有关另一个答案,请参阅来自构造函数和析构函数的纯虚拟调用。

于 2012-04-10T15:32:11.617 回答
0

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

最佳实践:不要从构造函数/析构函数内部调用虚函数。保持构造函数/析构函数非常简单,在 init() 函数或类似函数中完成其余工作。

于 2012-04-10T15:35:00.053 回答
0

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

感谢问题评论中的modelnine。

于 2012-04-10T15:36:59.480 回答