编辑:已解决
我现在正在开发一个多线程项目,其中有一个基础工作程序类,具有从中继承的各种工作程序类。在运行时,工作程序类成为线程,然后根据需要执行工作。
现在,我已经编写了一个Director,该Director应该维护一个指向所有 worker 的指针数组,以便它可以从他们那里检索信息,以及以后修改他们内部的变量。
我通过创建一个指向基类指针的指针来做到这一点:
baseWorkerClass** workerPtrArray;
然后,在Director的构造函数中,我为基 worker 类动态分配一个指针数组:
workerPtrArray = new baseWorkerClass*[numWorkers];
在每个工作程序线程的构造函数中,工作程序在Director中调用一个函数,该函数旨在将该工作程序的指针存储在数组中。
导演存储指针的方式如下:
Director::manageWorker(baseWorkerClass* worker)
{
workerPtrArray[worker->getThreadID()] = worker;
}
这是一个 worker 变量的例子。每个工作程序都继承自基本工作程序类,并且基本工作程序类包含应存在于所有工作程序变量中的纯虚函数,以及一些在所有工作程序之间共享的变量。
class workerVariant : protected baseWorkerClass
{
public:
workerVariant(int id)
: id(id)
{
Director::manageWorker(this);
}
~workerVariant()
{
}
int getThreadID()
{
return id;
}
int getSomeVariable()
{
return someVariable;
}
protected:
int id;
int someVariable
};
然后,baseWorkerClass看起来像这样:
class baseWorkerClass
{
public:
baseWorkerClass()
{
}
~baseWorkerClass()
{
}
virtual int getThreadID() = 0;
virtual int getSomeVariable() = 0;
};
在完成每个worker变量的初始化之后,我应该以指向baseWorkerClass对象的指针数组结尾。这意味着我应该能够例如使用其ID作为数组的索引来获取某个工作程序中给定变量的值,如下所示:
workerPtrArray[5]->getSomeVariable(); // Get someVariable from worker thread 5
问题是该代码导致Windows可执行文件崩溃,而没有任何原因的解释,而在Linux中,它说:
我可能发誓我曾经在某个时候完成过这项工作,所以我对自己搞砸的事情感到困惑。
实际的未修改的代码有问题:
worker 变量 header :http://pastebin.com/f4bb055c8
工作程序变体源文件:http://pastebin.com/f25c9e9e3
基本 worker 类 header :http://pastebin.com/f2effac5
基础 worker 类源文件:http://pastebin.com/f3506095b
导演 header :http://pastebin.com/f6ab1767a
导演源文件:http://pastebin.com/f5f460aae
编辑:额外的信息,在manageWorker函数中,我可以从指针“worker”调用任何纯虚函数,并且工作正常。在manageWorker函数之外,当我尝试使用指针数组时,它失败。
编辑:现在我考虑一下,线程的入口点是operator()。 Director线程是在工作线程之前创建的,这可能意味着重载的括号运算符在调用纯虚函数之前会被子类覆盖。我正在调查这个。
最佳答案
问题似乎是在Director::manageWorker
实例的构造函数中调用了workerVariant
:
Director::manageWorker(baseWorkerClass* worker) {
workerPtrArray[worker->getThreadID()] = worker;
}
大概
getThreadID()
不是纯粹的虚函数,否则(希望!)您将获得一个编译器错误,原因是未在workerVariant
中覆盖它。但是getThreadID()
可能会调用您应重写的其他函数,但这些函数在抽象类中被调用。您应该仔细检查getThreadID()
的定义,以确保在正确初始化子类之前,不要做任何依赖于子类的不良事情。更好的解决方案可能是将这种多阶段初始化分离为单独的方法,或者设计
Director
和baseWorkerClass
以使它们不具有这种初始化时的相互依赖性。