2013-06-28 64 views
5

我正在使用libPoco創建一個虛擬服務器來測試某些客戶端代碼。如何調用純虛函數

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是一個抽象類,而且我敢肯定,運行是一個純虛函數。 Pool.start(serveIt)似乎要求ServerRunnablerun。當我從控制檯運行它時,我始終得到pure virtual method called錯誤。但是,如果我在gdb中單步執行代碼,那麼我將成功接受來自客戶端的連接並向其發送數據。 ServerRunnablerun不是一個純粹的虛函數,應該被稱爲。

爲libPoco的線程代碼示例是在http://pocoproject.org/slides/130-Threads.pdf

我也在想,我可能會調用構造函數純虛方法,但並沒有什麼的構造器,我只是使用默認destuctor。有沒有辦法確定在哪裏調用純虛函數?在gdb中?謝謝。

回答

7

問題很可能是您的serverIt對象在調用方法之前超出了範圍。

您無法控制線程何時可以運行,因此它可能會在您的類的run方法被調用之前進行迭代,但隨後您的對象已被銷燬,並且其銷燬的過程虛擬功能表。

+2

我同意這可能是發生了什麼事。導致純虛擬函數被調用的一般情況是,在構造函數完成之前或析構函數開始之後調用虛函數。 –

2
Pool.start() 

啓動一個線程並返回。這就是爲什麼在PDF您鏈接自己的線程池的例子看起來是這樣的:

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

當你在gdb一步通了,你給線程的時間做它的事實例變量超出範圍了。