2013-06-28 21 views
5

Sto utilizzando libPoco per creare un server fittizio per testare qualche codice client.Come si chiama una funzione virtuale pura

class ServerRunnable: public Poco::Runnable { 
    public: 
ServerRunnable(StreamSocket conn) : conn(conn) { 
} 

void run(){ 
    string mess("Can you hear me?\n"); 
    try{ 
    this->conn.sendBytes(mess.c_str(), mess.size()); 
    } catch (Poco::Exception& ex){ 
    cerr << ex.displayText() << endl; 
    return; 
    } 
    cerr << "The message has been sent." << endl; 
} 

void setConn(StreamSocket inConn){ 
    this->conn = inConn; 
} 
    private: 
StreamSocket conn; 
}; 


int main(int argc, char **argv){ 
    ServerSocket s; 
    try{ 
    s.bind(8083, true); 
    } catch (Exception &ex){ 
    cerr << ex.displayText() << endl; 
    exit(1); 
    } 
    s.listen(124); 

    Poco::ThreadPool Pool(10, 25, 60, 128); 
    while(1){ 
    try{ 
     StreamSocket conn = s.acceptConnection(); 
     ServerRunnable serveIt(conn); 

     Pool.start(serveIt); 
    } catch (Exception &ex){ 
     cerr << ex.displayText() << endl; 
     Pool.joinAll(); 
     exit(1); 
    } 
    } 
    return 0; 
} 

Poco::Runnable è una classe astratta, e sono abbastanza sicuro che la corsa è una funzione virtuale pura. Pool.start(serveIt) sembra chiamare ServerRunnable 's run. Quando lo eseguo dalla console ottengo costantemente l'errore pure virtual method called. Tuttavia, se sono in gdb per passare il codice, accetterò con successo la connessione dal client e invierò i dati. ServerRunnable 's run non è una pura funzione virtuale e questo è ciò che dovrebbe essere chiamato.

esempi di codice per Threading libPoco sono a http://pocoproject.org/slides/130-Threads.pdf

Sto anche pensando che io possa essere chiamata al metodo virtuale pura nel costruttore, ma non c'è niente nella contructor e sto semplicemente utilizzando il destuctor predefinito. C'è un modo per inchiodare dove e quale pura funzione virtuale viene chiamata? In gdb? Grazie.

risposta

7

Il problema è più probabile che l'oggetto serverIt esca dall'ambito prima che venga chiamato il metodo run.

Non si ha alcun controllo su quando un thread può essere eseguito, quindi potrebbe essere che il ciclo itera prima che venga chiamato il metodo run della classe, ma poi il tuo oggetto è stato distrutto e con la sua distruzione ovviamente la tabella delle funzioni virtuali.

+2

Sono d'accordo che è probabile che cosa sta succedendo. La circostanza generale che provoca la chiamata di una funzione virtuale pura è che la funzione virtuale viene invocata prima che il costruttore completi o dopo che il distruttore abbia avuto inizio. –

2
Pool.start() 

avvia una discussione e restituisce. È per questo che nel PDF si è collegato il loro esempio di thread si presenta così:

main() 
    Poco::ThreadPool::defaultPool().start(runnable); 
    Poco::ThreadPool::defaultPool().joinAll(); 
    return 0; 

Quando fate un passo attraverso di essa in gdb, ti danno il tempo di thread per fare la sua cosa prima che la variabile di istanza va fuori di portata.

Problemi correlati