“Metodo virtuale puro chiamato” quando si implementa un'interfaccia involucro boost :: filo
-
01-10-2019 - |
Domanda
Ho un piccolo involucro che centralizzare ciò che è relativo a discussioni:
class Thread {
protected:
boost::thread *m_thread;
virtual void work() = 0;
void do_work() {
work();
}
public:
Thread() : m_thread(NULL) {}
virtual ~Thread() {
catch_up();
delete m_thread;
}
inline void catch_up() {
if(m_thread != NULL) {
m_thread->join();
}
}
void run() {
m_thread = new boost::thread(boost::bind(&Thread::do_work, boost::ref(*this)));
}
};
Quando ho attuarlo, dire con la seguente:
class A : public Thread {
void work() {}
};
A:
A a; a.run();
Ho una terminazione runtime con un "metodo virtuale puro chiamato" abbastanza visualizzato. Penso che sia l'argomento boost :: bind, ma non so come dire "Usa virtuale pura implementazione" ...
Grazie anticipato d'.
Saluti,
di Mister Mystère
Soluzione
Il tuo incidente accade solo quando il programma termina subito: le chiamate distruttore di classe di A, che finiture e chiede distruttore di discussione prima il filo appena avviato ha avuto la possibilità di essere programmato. Il thread chiama quindi la funzione virtuale, ma di classe A non esiste più, quindi tenta di chiamare do_work di discussione (), che chiama il lavoro virtuale pura (). Ecco il programma con uscite extra:
run() started
run() ended
~A() started
~A() ended
~Thread() started
catch_up() started
do_work() started
pure virtual method called
standard-saggio, credo che questo sia un comportamento indefinito perché tutta la vita dell'oggetto è già terminato (chiamata distruttore ha cominciato) quando un riferimento ad essa (boost::ref(*this)
) è stato utilizzato per chiamate do_work () dal thread.
Soluzione: lasciate che il vostro filetto eseguire prima di distruggere l'oggetto:
A a; a.run();
a.catch_up();
O, come la documentazione boost.thread dice, " l'utente Boost.Thread deve garantire che il cui-ad oggetto sopravvive al filo appena creato di esecuzione ".
Altri suggerimenti
sto andando su un arto qui, ma ho il sospetto che il problema è con il distruttore Discussione:
virtual ~Thread() {
catch_up();
delete m_thread;
}
Se il filo non è ancora iniziata, chiamando catch_up()
nel distruttore inizierà il filo spinta utilizzando vtable del thread, piuttosto che una di, come in C ++ al punto di distruttore della partite vtable la portata del tipo di distruttore, non vtable più derivata.