2012-04-10 2 views
0

У меня есть немного модифицированная версия класса потока скопированного выключить 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, а class Product создает его поток позже во время выполнения программы.

Теперь дело в том, class Item отлично работает. Вызывается и обрабатывается функция run. Однако, когда class Product вызывает ту же функцию позже, я получаю:

pure virtual method called 

Оба класса имеют одинаковую реализацию с перегрузкой метода run, но один называется, а другой нет.

Зачем мне внезапно получать исключение pure virtual method called?

Спасибо.

Update: class Item отличается class Product, потому что Item объявлен как static Item item; в файле CPP, и есть только один. class Product используется как обычный объект. Если я делаю то же самое с class Product, он отлично работает.

+0

Вы уверены, что 'Product' не является производным от' Item'? Это объясняет ошибку. – modelnine

+0

@PlasmaHH - Исключение исходит из класса, вызываемого обычно. Вызов из ctor («Элемент») работает правильно. – user626201

+0

@modelnine - нет, они совершенно разные классы. Соединение отсутствует, даже в заголовке нет (кроме заголовка потока). – user626201

ответ

0

Благодаря тому, что указано на модели, мы обнаружили, что код нарушения создавал объект, начиная поток, а затем уничтожал объект, прежде чем поток получил шанс запустить. Это, как указано в моделировании, удаляет vtable, и это вызывает проблему.

Благодаря модели в комментариях к вопросу.

1

Не вызывайте виртуальные функции от конструктора или деструктора - цепочка наследования неполна, когда код запущен и в этом случае нет значимого способа вызова виртуальных функций. См. Pure virtual invocation from constructor and destructor для получения другого ответа.

0

Элемент и продукт: public Thread означает, что вы вызовете виртуальную функцию (внутри себя) внутри конструктора. Внутри конструктора vtable еще не настроен полностью (поскольку он зависит от инициализации каждого из базовых классов), поэтому вы получите неопределенное поведение.

Лучшая практика: не вызывайте виртуальные функции изнутри конструктора/деструктора. Храните конструкторы/деструкторы очень просто, выполняйте остальную часть работы внутри функции init() или такой.

+0

@phresnel: запрещается только вызывать виртуальную функцию * pure *; вызов нечистой функции из конструктора хорошо определен и иногда может быть разумным делом. –

+0

@MikeSeymour: Как-то я на самом деле читаю «чистый», но, по-моему, мои подсознательные жонглируемые слова слишком много читают. –

Смежные вопросы