“Metodo virtuale puro chiamato” quando si implementa un'interfaccia involucro boost :: filo

StackOverflow https://stackoverflow.com/questions/3160403

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

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top