我在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 called
与class Item
不同,因为class Product
在cpp文件中被声明为Item
,并且只有一个。 static Item item;
与普通对象一样使用。如果我对class Product
执行相同的操作,则可以正常工作。
答案 0 :(得分:1)
不要从构造函数或析构函数中调用虚函数 - 当代码在其中运行时,继承链是不完整的,因此,调用虚函数没有任何有意义的方法。有关其他答案,请参阅Pure virtual invocation from constructor and destructor。
答案 1 :(得分:0)
Item和Product是:public Thread意味着你可以在构造函数中调用一个虚函数(自身)。在构造函数内部,vtable尚未完全设置(因为它依赖于正在初始化的每个基类),因此您将获得未定义的行为。
最佳实践:不要在构造函数/析构函数中调用虚函数。保持构造函数/析构函数非常简单,在init()函数中执行其余的工作等。
答案 2 :(得分:0)
感谢modelnine所指出的,我们发现有问题的代码是在线程有机会运行之前创建一个对象,启动线程然后销毁对象。正如模型所示,这是删除vtable,这导致了问题。
感谢问题评论中的modelnine。