2013-06-28 14 views
5

Używam libPoco do utworzenia fałszywego serwera w celu przetestowania kodu klienta.Jak nazywa się czystą wirtualną funkcję?

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 jest klasą abstrakcyjną, a jestem pewien, że bieganie jest czystą funkcją wirtualną. Wydaje się, że Pool.start(serveIt) wywołuje ServerRunnable 's run. Kiedy uruchomię go z konsoli, konsekwentnie dostaję błąd pure virtual method called. Jeśli jednak przejdę przez kod gdb, to z powodzeniem zaakceptuję połączenie od klienta i wyślę je. ServerRunnable 's run nie jest czystą funkcją wirtualną i właśnie taką należy nazwać.

przykłady kodu dla libPoco za Threading są http://pocoproject.org/slides/130-Threads.pdf

Myślę też, że może być wywołanie czystej metody wirtualnej w konstruktorze, ale w contructor nie ma nic, a ja po prostu przy użyciu domyślnego destuctor. Czy jest jakiś sposób, aby ustalić, gdzie i jak nazywa się czysta funkcja wirtualna? W gdb? Dzięki.

Odpowiedz

7

Najprawdopodobniej problem z wykryciem obiektu serverIt wykracza przed wywołaniem metody run.

Nie masz żadnej kontroli nad tym, kiedy wątek może działać, więc może się zdarzyć, że pętla będzie iterować przed wywołaniem metody klasy run, ale wtedy obiekt został zniszczony, a wraz z nim jego zniszczenie wirtualna tabela funkcji.

+2

Zgadzam się, że prawdopodobnie to się dzieje. Ogólna okoliczność, która powoduje wywołanie funkcji czysto wirtualnej, polega na tym, że funkcja wirtualna jest wywoływana albo przed rozpoczęciem konstruktora, albo po rozpoczęciu destruktora. –

2
Pool.start() 

uruchamia wątek i wraca. Dlatego w PDFie jesteś połączony ich pula wątków przykład wygląda następująco:

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

Kiedy krok thru nim w gdb, dać czas wątek do zrobienia jego rzecz przed zmienną instancji wykracza poza zakres.

Powiązane problemy