jak*_*gut 10 c++ inheritance multithreading pure-virtual
编辑:已解决
我现在正在开发一个多线程项目,我有一个基础工作者类,具有从中继承的不同工作类.在运行时,工作类成为线程,然后根据需要执行工作.
现在,我有一个我写过的Director,它应该维护一个指向所有worker的指针数组,以便它可以从中检索信息,以及稍后修改它们中的变量.
我通过创建指向基类指针的指针来完成此操作:
baseWorkerClass** workerPtrArray;
Run Code Online (Sandbox Code Playgroud)
然后在Director的构造函数中,我动态地为基础worker类分配一个指针数组:
workerPtrArray = new baseWorkerClass*[numWorkers];
Run Code Online (Sandbox Code Playgroud)
在每个工作线程的构造函数中,worker调用director中的一个函数,该函数用于将该worker的指针存储在数组中.
以下是导演存储指针的方式:
Director::manageWorker(baseWorkerClass* worker)
{
workerPtrArray[worker->getThreadID()] = worker;
}
Run Code Online (Sandbox Code Playgroud)
以下是工人变体的示例.每个worker都继承自基类worker类,而base worker类包含纯虚函数,这些函数应该存在于所有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
};
Run Code Online (Sandbox Code Playgroud)
然后baseWorkerClass看起来像这样:
class baseWorkerClass
{
public:
baseWorkerClass()
{
}
~baseWorkerClass()
{
}
virtual int getThreadID() = 0;
virtual int getSomeVariable() = 0;
};
Run Code Online (Sandbox Code Playgroud)
在每个worker变量完成初始化之后,我应该得到一个指向baseWorkerClass对象的指针数组.这意味着我应该能够,例如,使用其ID作为数组的索引来获取某个工作中给定变量的值,如下所示:
workerPtrArray[5]->getSomeVariable(); // Get someVariable from worker thread 5
Run Code Online (Sandbox Code Playgroud)
问题是这段代码导致Windows可执行文件崩溃,没有任何解释原因,在Linux中,它说:
名为
terminate的纯虚方法在没有活动异常的情况下被调用
Aborted
我可以发誓我曾经在某个时候工作过,所以我很困惑我搞砸了什么.
有问题的实际未修改代码:
Worker变量头:http://pastebin.com/f4bb055c8
Worker变量源文件:http://pastebin.com/f25c9e9e3
基础工作者类头:http://pastebin.com/f2effac5
基本工作者类源文件:http://pastebin.com/f3506095b
主管标题:http://pastebin.com/f6ab1767a
导演源文件:http://pastebin.com/f5f460aae
编辑:额外的信息,在manageWorker函数中,我可以从指针"worker"调用任何纯虚函数,它工作得很好.在manageWorker函数之外,当我尝试使用指针数组时,它会失败.
编辑:现在我考虑一下,线程的入口点是operator().Director线程在worker之前创建,这可能意味着重载的括号运算符在被子类覆盖之前调用纯虚函数.我在调查这个.
Joh*_*lla 12
问题似乎Director::manageWorker
是在workerVariant
实例的构造函数中调用:
Director::manageWorker(baseWorkerClass* worker) {
workerPtrArray[worker->getThreadID()] = worker;
}
Run Code Online (Sandbox Code Playgroud)
大概getThreadID()
不是一个纯粹的虚函数,或者你会(希望!)得到一个关于不覆盖它的编译器错误workerVariant
.但是getThreadID()
可能会调用你应该覆盖的其他函数,但是在抽象类中调用它们.你应该仔细检查一下这个定义,getThreadID()
以确保在正确初始化之前你没有做任何不利于子类的事情.
更好的解决方案可能是将这种多阶段初始化分离为单独的方法,或设计Director
并使baseWorkerClass
它们没有这种初始化时间相互依赖性.
归档时间: |
|
查看次数: |
36120 次 |
最近记录: |