РЕДАКТИРОВАТЬ: РЕШЕНО
Я сейчас работаю над многопоточным проектом, где у меня есть базовый рабочий класс с различными рабочими классами, которые наследуются от него. Во время выполнения рабочие классы становятся потоками, которые затем выполняют работу по мере необходимости.
Теперь у меня есть директор, которого я написал, который должен поддерживать массив указателей для всех работников, чтобы он мог получать от них информацию, а также изменять переменные внутри них позже.
Я сделал это, создав указатель на указатель базового класса:
baseWorkerClass** workerPtrArray;
Затем в конструкторе Director я динамически выделяю массив указателей на базовый рабочий класс:
workerPtrArray = new baseWorkerClass*[numWorkers];
В конструкторе каждого рабочего потока рабочий вызывает в директоре функцию, которая предназначена для хранения указателя этого рабочего в массиве.
Вот как директор хранит указатели:
Director::manageWorker(baseWorkerClass* worker)
{
workerPtrArray[worker->getThreadID()] = 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;
};
После завершения инициализации каждого рабочего варианта я должен получить массив указателей на объекты baseWorkerClass. Это означает, что я должен иметь возможность, например, получить значение заданной переменной у определенного работника, используя его идентификатор в качестве индекса для массива, например:
workerPtrArray[5]->getSomeVariable(); // Get someVariable from worker thread 5
Проблема в том, что этот код вызывает сбой в исполняемом файле Windows без объяснения причин, а в Linux он говорит:
чисто виртуальный метод с именем
завершить вызов без активного исключения
Прервано
Я мог бы поклясться, что в какой-то момент это сработало, так что я запутался в том, что я облажался.
Фактический неизмененный код, имеющий проблему:
Рабочий вариант заголовка: http://pastebin.com/f4bb055c8
Исходный файл варианта работника: http://pastebin.com/f25c9e9e3
Заголовок базового рабочего класса: http://pastebin.com/f2effac5
Исходный файл базового рабочего класса: http://pastebin.com/f3506095b
Заголовок директора: http://pastebin.com/f6ab1767a
Исходный файл директора: http://pastebin.com/f5f460aae
РЕДАКТИРОВАТЬ: Дополнительная информация, в функции manageWorker, я могу вызвать любую из чисто виртуальных функций из указателя «работник», и она работает просто отлично. За пределами функции manageWorker, когда я пытаюсь использовать массив указателей, происходит сбой.
РЕДАКТИРОВАТЬ: Теперь, когда я думаю об этом, точка входа потока является оператор (). Поток Director создается перед рабочими, что может означать, что перегруженный оператор скобок вызывает чисто виртуальные функции, прежде чем они могут быть переопределены дочерними классами. Я смотрю на это.